Tải bản đầy đủ - 0 (trang)
Chapter 10. Camera, Map Kit, and Core Location: Proof in the real world

Chapter 10. Camera, Map Kit, and Core Location: Proof in the real world

Tải bản đầy đủ - 0trang

be the developer solution


BE the developer solution

What happens if Core Location can’t get anything or the user disables it?

Since Bob needs the location info when he marks a fugitive as captured, we’ll

need to disable the captured switch if we can’t get anything.

- (CLLocationManager*) locationManager {

if (locationManager_ == nil) {

locationManager_ = [[CLLocationManager alloc] init];

locationManager_.desiredAccuracy =




locationManager_.delegate = self;

er. If we

This is the property gelocttation manager

haven’t configured a re.

yet, we’ll set it up he

The location manager wi

notify the delegate (us)ll

it gets a valid position up when


return locationManager_;

- (void) locationManager:(CLLocationManager *)manager

didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation

*)oldLocation {

NSLog(@”%@”, @”Core location claims to have a position.”);


self.capturedToggle.enabled = YES;

If the location mana

get a fix, it will sendgeusr can’t



- (void) locationManager:(CLLocationManager *)manager

didFailWithError:(NSError *)error {

NSLog(@”%@”, @”Core location can’t get a fix.



Disabling capture

self.capturedToggle.enabled = NO;

n’t have a nice

Since the segmented controller really doesusing

a UIAlertView


disabled look, you might want to cons






to warn the user that they can’t mar

540   Chapter 10



camera, map kit, and core location


When will you shut down Core Location?

We’ll shut it down when we leave the detail view.

- (void) viewWillDisappear:(BOOL)animated {

[super viewWillDisappear:animated];

NSLog(@”%@”, @”Shutting down core location.”);


Make sure you shut do


location manager when wn



need it to conserve batt don’t


[self.locationManager stopUpdatingLocation];


- (void)dealloc



[fugitive_ release];

[nameLabel_ release];

[idLabel_ release];

[descriptionTextView_ release];

[bountyLabel_ release];

[capturedToggle_ release];

[capturedDateLabel_ release];

What about other devices?

We’re good. All we do is tell Core

Location the accuracy we want and

it deals with the rest. So, the iPod

Touch can get just the best data it

can, and we’ll get that.

[capturedLatLon_ release];

[locationManager_ release];


[super dealloc];

Implement all this

code and then

take it for a spin...

you are here 4   541


no dumb core location questions


We start and stop Core Location in viewWillAppear and

viewWillDisappear. Is that normal?


It’s normal to start and stop Core Location as you need it. It

uses a fair amount of power while it’s running, so it’s best to shut

it down if you don’t need it. This gets a little tricky because Core

Location can require some time to get its initial position information.

To try to make that a little smoother for the user, we enable it as soon

as the view appears to give it a head start before the user needs the




Is there any way to speed up that initial position?

Core Location will try to cache previous position information

so it can give you something as quickly as possible. Because of

this, if you’re really concerned about accuracy, you should check the

timestamp sent along with the position information to make sure the

position is recent enough for your needs.


Does location accuracy impact things like startup time or

battery usage?


Absolutely. The more accurate a position you ask for, the more

battery Core Location will consume, and it will potentially take longer

to figure out. Lower-fidelity information tends to come to you faster. 

Use whatever accuracy you need for your application, but be aware

of the implications of high-resolution information.


No. Core Location, like a lot of other frameworks in iOS, calls

back asynchronously as data is available. Network access generally

works this way as well. You need to make sure you keep your users

informed of what’s going on in the application and what they can and

can’t do at the moment. For example, we disable the Captured button

if there’s no position information available. Other options display a

wait indicator (like a spinning gear) or display position status with a

disabled indicator like an icon, button, or label.


Why did we have to move the code around and do all that



We did it to follow the DRY principle (Don’t Repeat Yourself). We

cleaned up the code and eliminated duplication by pulling it out into a

separate method and calling that from the two places that need it



What’s the deal with the private interfaces again?

Remember that our header file captures our public interface or

API. We don’t want this internal method to be part of our API (in other

words, we don’t want other people to call it). We still want to declare

it so the compiler can check that we’re calling a valid method, so we

add a Private set of methods to our interface in the implementation

file. Some people actually put an _ (underscore) before their private

method names so that it’s obvious that you shouldn’t be calling this

from anywhere but the class’s own implementation. Apple, however,

reserves this convention for their private methods.


Is there a way to just wait for Core Location to have a

position rather than having it call back to the delegate like that?

542   Chapter 10


camera, map kit, and core location

Test Drive

Implementing Core Location really wasn’t that hard, but making it work in the user

flow required a bit more work. Now that it’s all done, you should be up and running...


To operate the app here, Bow,b wil







navigate into






will kick off the


shoplifting jewelry

Since we added capturedToggle.

enabled = NO; to the


viewWillAppear, the user canCo

engage the control before reates.

Location starts returning upd

When the user navigates away from

the detail view, Core Location shuts

down to save batteries.

It’s working! Bob

should be psyched...

you are here 4   543


bob gets visual

Just latitude and longitude

won’t work for Bob

That’s great for my forms and

everything, but I’m more of a

visual person...

It’s an iPhone. A map

would really be more


What’s the point of all the network

connectivity and fancy graphics if

we just show a text field? With just a

little bit of code and the iOS Map

Kit, we’ve got something a lot more

appealing in the works.

544   Chapter 10


camera, map kit, and core location

Map Kit comes with iOS

When Apple opened up the API for the Map Kit in iOS 3.0,

developers gained access to the maps that come from Google

maps, including satellite imagery.

There’s lots of customization that you can do with the maps, such

as how wide an area they show, what view they start with, and

pins and annotations.

Logistically, using Map Kit is a lot like Core Location: you’ll need

a new framework and will have to #import

in the header file.

MKMapView is a control

that pulls map information

from Google Maps. You

can configure it for the

normal road display, satellite

imagery, or a hybrid, like you

see here.

Map Kit comes with built-in

support for pushpins at specified

locations, called annotations.

Depending on the

information you

want to show on the

map, you can create

your own views for

annotations and

show anything you

want, like pictures,

formatted text, etc.

Map Kit requires a network connection.

Since Map Kit pulls imagery information from Google,

you’ll need to have a network connection for it to be useful.

That’s not a problem for the simulator (assuming your

Mac is online), but it could be an issue for any device with

limited connectivity, depending on the location. Map Kit handles this

gracefully, but it’s something to be aware of.

How can we put

this to work?

you are here 4   545


map custom setup

A little custom setup for the map

Like Core Location, it’s not a lot of work to get basic Map Kit support

going in iBountyHunter. We’re going to create another private method

called initializeMapView that we’ll call from viewWillAppear in the

CapturedPhotoViewController to display the capture location on a hybrid

(satellite plus road information) map.


- (void) initializeMapView {


if ([fugitive_.captured boolValue]) {

CLLocationCoordinate2D mapCenter = CLLocationCoordinate2

DMake([fugitive_.capturedLat doubleValue], Here, we’ll pass in the value

These values

allow us to

configure the

size of the

default map


of the lat and lon where the

fugitive was captured.

[fugitive_.capturedLon doubleValue]);

MKCoordinateSpan mapSpan = MKCoordinateSpanMake(0.005,


MKCoordinateRegion mapRegion = MKCoordinateRegionMake(ma

pCenter, mapSpan);

We pull al

l thi

information tosge

initialize the mapther to




self.mapView.region = mapRegion;

self.mapView.mapType = MKMapTypeHybrid;

There are a few map types; hybrid is

both satellite and road information.

The mapRegion specifies

should be centered and howhere the map

be visible north and sout w much should

This effectively sets the h (in degrees).

zoom level of

the map.

546   Chapter 10


The size of the map is in

degrees. We want the map

to be pretty zoomed in.

camera, map kit, and core location



What’s the difference between Core Location and Map Kit?

Map Kit is about displaying a map, position-sensitive

information, and user interface. Core Location is about getting

you information about where you are. You can drag and drop a

map onto your view in Interface Builder; you pass it some values

and it just works.

Core Location, on the other hand, returns values to the delegate, and

you need to decide what to do with them. We’re going to take that

information from Core Location and give it to Map Kit to show us a

map of the capture location, for example.


Where do all these frameworks come from? What if I want

one that’s not on the list?


The frameworks are included as part of the SDK. The actual

path to the frameworks varies by version and what platform you’re

developing for. For example, the Map Kit framework we’re using is

here: /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/

iPhoneOS4.3sdk/System/Library/Frameworks/MapKit.framework. In

general, you should be able to add frameworks using the method we

described in Xcode and not need to worry about a specific location,

but if a framework isn’t listed or you’re adding a custom one, you can

point Xcode to the actual path.

Implement the map to show the area where

the fugitive was captured.


Add the Map Kit framework and the #import.

Add the framework just like we did with Core Location. While

you’re at it, make sure that you do the #import in the detail view

to include the Map Kit header.


Configure the photo view to show the map.

Rather than adding a whole new view, go ahead and add the map

to the CapturedPhotoView with the image. Resize the image and

the button then drag an MKMapView to the bottom half of the



Add the outlets and code for the MKMapView.

Now that you have all the support stuff in place, go ahead and

add the outlets and the actual Map Kit code we gave you to make

the map work. Make sure you wire up the outlet in Xcode and

call the new initializeMapView method in viewWillAppear.

Resize the image

and the button...

...and use the

bottom of the

view for the


you are here 4   547


exercise solution

Implement the map to show the area where the fugitive was captured.


Add the Map Kit framework and the #import.

Here’s the Map Kit



@interface CapturedPhotoViewController :

UINavigationControllerDelegate, UIActionSheetDelegate> {


UIImageView *fugitiveImage_;


Fugitive *fugitive_;


MKMapView *mapView_;

Add the

outlets and

code for the

Map Kit.

@property (nonatomic, retain) IBOutlet MKMapView




548   Chapter 10


camera, map kit, and core location


Configure the photo view to show the map.

Resize the image

and the button...

...and use the

bottom of the

view for the


Just drag thefrom the

MKMapViewhe view.

library to t

you are here 4   549


exercise solution


Add the outlets and code for the MKMapView.

@interface CapturedPhotoViewController (Private)

- (void) initializeMapView;


@synthesize fugitiveImage=fugitiveImage_;

@synthesize fugitive=fugitive_;

@synthesize mapView=mapView_;

- (void) viewWillAppear:(BOOL)animated {

[super viewWillAppear:animated];

If the fugitiv

then we ask UeIImhas image data,

image from it an age to create an

d set it on our

image view.

if (fugitive_.image != nil) {

self.fugitiveImage.image = [UIImage




[self initializeMapView];


550   Chapter 10


Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 10. Camera, Map Kit, and Core Location: Proof in the real world

Tải bản đầy đủ ngay(0 tr)