Wednesday, April 22, 2009

Creating Location-Aware iPhone Applications with CoreLocation

The inclusion of GPS on the iPhone opened up a world of possibilities for application developers. Developers could now create location-aware applications: applications that take into account the user's location when determining what action to take or what content to display. The cornerstone of this location support is Apple's CoreLocation API. This article provides a look at how you can develop location-aware applications using CoreLocation.

CoreLocation functions using several different mechanisms for determining a user's location. This includes GPS, cell-tower triangulation, and (according to reports) Wi-Fi network location databases. In older hardware that does not support GPS, this mechanism is expectedly missing. Each of these mechanisms varies in their accuracy, with GPS generally being considered the most accurate. However, regardless of what your target hardware supports, you can generally get a good sense of a user's location using CoreLocation.

Before you can begin developing your application with CoreLocation, you need to add the CoreLocation framework to your XCode project. This framework is located at:

/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.0.sdk/System/Lbrary/Frameworks

You may change iPhoneSimulator2.0.sdk to match your application's target platform. Once this framework is included, you can begin developing location-aware applications.

The CLLocation object represents the actual location information. This includes not only latitude/longitude, but also speed, course, and altitude information. The CLLocation object is generated and returned by the CLLocationManager object. The CLLocationManager is used to deliver location events to your application via the CLLocationManagerDelegate protocol.

The CLLocationManager class allows you to specify various parameters to be used when determining location information. The distanceFilter parameter specifies how much a device must move laterally before a location update event is triggered. For example, if you were writing an application that tracks how far you drive over a period of time, you may want to have a larger distance filter set than you would for an application that tracks how far you walk over a period of time. Of particular importance is the desiredAccuracy parameter. This parameter specifies how accurate the location returned should be. There are 5 supported values for this parameter: kCLLocationAccuracyBest, kCLLocationAccuracyNearestTenMeters, kCLLocationAccuracyHundredMeters, kCLLocationAccuracyKilometer, and kCLLocationAccuracyThreeKilometers. The desired accuracy is one of the things that must be taken under consideration when scoping the requirements of your application. If you are looking for course grained location information -- that is, what city a user is in as opposed to which street corner they are standing at -- then you may not need to incur the penalties that highly accurate location information comes with. Performance is of key importance when determining what accuracy to require. This includes processing performance, battery life performance, as well as the amount of time required to provide the location. When you initially request a location, the CLLocationManager provides the quickest -- and least accurate -- location available. It then works to further refine the location to ensure it is the most accurate. If getting a rough location quickly is more important to your application than pinpointing exactly where your user is, then you may want to use a less accurate measure than someone else developing a geocaching application.

Now that we've discussed some of the basics of CoreLocation, let's take a look at how to include it within your application. To start, whatever object will be making use of the location information must implement the CLLocationManagerDelegate protocol. This protocol contains 2 methods:

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error

and

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

The didFailWithError method is called whenever location services are unable to determine a user's location. This includes situations where a user denies your application permission to determine the location. The didUpdateToLocation method is called whenever a successful location has been performed. The newLocation parameter provides the new coordinate information, while the oldLocation parameter has the previous location information. If this is the first time that didUpdateToLocation has been called, oldLocation will be nil.

To start using CoreLocation, you must instantiate a CLLocationManager object like so:


#import

...snip...

CLLocationManager *locationManager = [[CLLocationManager alloc] init];

// Set the delegate
locationManager.delegate = self;

// Set your accuracy and filter parameters here
locationManager.distanceFilter = ...
locationManager.desiredAccuracy = ...

[locationManager startUpdatingLocation];

...snip...


The startUpdatingLocation method begins the process of determining the user's location based on the specified parameters. When a successful location is determined, it will call didUpdateToLocation on the specified delegate object. We can now write out our delegate methods:


- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
// Disable future updates to save power.
[locationManager stopUpdatingLocation];

NSLog(@"oldLocation : %@", oldLocation);
NSLog(@"newLocation : %@", newLocation);
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {

[locationManager stopUpdatingLocation];

NSLog(@"ERROR : %@", error);
}


You notice here that we call stopUpdatingLocation as soon as a location is determined. This is to preserve battery life, as location services do draw quite a bit of power. If you have specified a high level of accuracy, you may not want to stop updating immediately, as it takes a while to get very accurate location results.

This was a quick introduction into how the CoreLocation classes work. With the 3.0 firmware including Google Maps support, you should be able to get map-based applications up and running with little effort. If you can't wait until then, take a look at Route-Me for an EXCELLENT mapping component for your iPhone or iPod Touch. I'm using it in one of my applications, and can't recommend it highly enough.

Thursday, April 16, 2009

4 (+1) Priceless iPhone Development Blogs

If you're like me, you'll find the best way to learn new technologies or techniques is not by reading the "official" product documentation, but by studying the works of others. I've learned most of what I've learned about iPhone development not by reading Apple's developer documentation, but by studying what other developers have done with their apps. To that end, I've compiled a list of the most useful iPhone development blogs that I've found. I'm sure you'll find yourself writing much better code after you look at some of the things these developers have done.

0. iDev4iPhone

(aka This Blog) Yes, it's shameful that I plug my own blog in this post. However, it's worth subscribing to. I strive to regularly post on useful topics, but I also know the value of posting links to valuable resources I've come across. I'll be sure to share the knowledge whenever I get the chance.

1. iCodeBlog

iCodeBlog has some very detailed information, particularly with respect to game development. Game development is one of the hottest areas in Apple's AppStore, but there really isn't as much useful documentation about it on the web. Although iCodeBlog doesn't have as much content as some other sites, what is there is very useful and easy to understand.

2. iPhone Developer Tips

iPhone Developer Tips contains a wealth of information on several different topics. The content is not iPhone specific, in spite of its name. This blog also includes numerous tips on general Cocoa/Objective-C development. The XCode hints and tips, alone, make this site worth subscribing to.

3. iPhone SDK Articles

iPhone SDK Articles provides some of the most practical articles on iPhone development around. Many of them are targetted to new developers, making this one of the most valuable resources when beginning your first project. This blog also covers a lot of topics that are often overlooked, such as how to make advanced use of SQLite or Internationalization.

4. Mobile Orchard

Mobile Orchard is one of my favorite iPhone development blogs because of the shear volume of information it provides on a broad range of topics. The focus is not just on "How to Code X, Y, or Z." There is also tons of practical information on the AppStore and general programming topics. Their article on avoiding AppStore rejection should be required reading for all new iPhone developers.


Good luck!