Jump to content

How to effectively use Core Location in your iPhone app

+ 3
  TheBarbarianGroup's Photo
Posted Sep 30 2009 03:55 PM

The iPhone gives developers several methods of detecting the physical location of a device. This is by far one of its most innovative features and has helped create many new business models and usage patterns. Developers have released location-aware applications ranging from social network clients to restaurant review tools to mapping applications to games.

The framework used for adding location awareness to an application is called Core Location, and it is a powerful and impressive toolset. It also comes with a price and some limitations. For example, finding the location of a device takes a lot of power, potentially leading to battery drainage. The more accurate the request, the more power is used. Battery life is a constant concern for developers of mobile applications, and Core Location forces developers to balance their needs with the desire to minimize power use. This is one reason that a turn-by-turn navigation system is a challenge for the iPhone.

Another trade-off when you add Core Location support to an application is the increased risk of feature fatigue. Feature fatigue is the feeling that a product or tool—such as an iPhone application—has too many options and is too complex. One of the differentiators of the Mac and iPhone user experience over other platforms is the clarity and sense of purpose in high-quality applications. Apple users tend to prefer smaller, more polished feature sets to larger, less elegant software.

A final downside to adding Core Location support is the result of a default security policy that requires users to grant permission to each application making location requests. This is something users become accustomed to over time, but for users new to the platform, it can be disconcerting. Figure 1 shows the permission prompt for the Maps application.

Figure 1. A Core Location permission prompt in the Maps application

Attached Image

Like many features of the iPhone, users can disable location support in the Settings application. The use cases you create for location-aware applications should factor in the possibility of users turning off support for Core Location. Marketing materials and App Store entries for applications that require Core Location should mention the requirement so that users who prefer not to share their location can make informed decisions. Figure 2, shows the option in the Settings application for disabling location support across all applications.

In cases where location services are disabled, users might be prompted to enable those services. Figure 3, shows the Maps application after launching on an iPhone with location services disabled.

None of these potential drawbacks is meant to discourage developers from adding location awareness to their applications. Rather, they’re meant to be considered as part of due diligence for developers focused on creating quality user experiences. Just as some applications simply cannot function without a live network connection, location awareness is the crux of many applications.

Basic integration of location awareness is trivial. CLLocationManager is a class that resolves geographical location within a supplied radius. When a position is found, the class notifies a delegate object.

Core Location uses three methods of deriving location. The iPhone will choose the method that best suits the needs of the application. Developers can, in most cases, ignore the means used to locate a device and instead focus on the details of their request:

// Access the location manager

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

Figure 2. The Settings application allows users to disable location services for all applications

Attached Image

Figure 3. The Maps application with location services disabled

Attached Image

CLLocationManager lets you search for the current location. Each location manager should have a delegate assigned. A delegate can be any object that implements the CLLocationManagerDelegate protocol. The protocol is quite simple, consisting of only two event management methods: one representing a successful location search or refinement, and another representing a failure in deriving the location of a device.

A location manager object defines an instance property that can be used to set the desired accuracy for a Core Location request. The property is named, aptly enough, desiredAccuracy. The possible values for the desired accuracy are defined as constant double values of the type CLLocationAccuracy, and are described in the following list:

kCLLocationAccuracyBest

This value represents a request for the highest possible precision given the current conditions. This is a very expensive option because of the work required to derive the highest precision.

kCLLocationAccuracyNearestTenMeters

This value represents a request for accuracy within 10 meters.

kCLLocationAccuracyHundredMeters

This value represents a request for accuracy within 100 meters.

kCLLocationAccuracyKilometer

This value represents a request for accuracy within one kilometer.

kCLLocationAccuracyThreeKilometers

This value represents a request for accuracy within three kilometers. This option is preferable if you simply need to know the country, state, province, city, or town in which a device is located.

Setting the desired accuracy is simple:

locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;

// Set the delegate to handle the messages from the location manager

locationManager.delegate = self;

// Set the minimum distance the iPhone must move from its initial location

// before the delegate will be notified

locationManager.distanceFilter = 100.0f;

[locationManager startUpdatingLocation];

A location manager will continue to poll its sources in attempts to achieve an accuracy that is as close as possible to the stated desiredAccuracy. As it makes refinements, it will notify its delegate of changes, passing the new and prior locations to the delegate method locationManager:didUpdateToLocation:fromLocation. There is no guarantee that the desired accuracy will be achieved, or that it can be maintained in cases where the location manager is allowed to continuously seek new locations over time. When developing user interface elements that display the location, design for the unpredictable accuracy Core Location can provide. The Maps application handles the inherent imprecision of location services well. As the application refines location accuracy, the Maps application draws a circle with a radius that corresponds roughly to the accuracy of a given request. With each refinement, the circle animates and shrinks to show the new radius value. The radius represents the margin of error. Errors in precision still occur on occasion—showing that a user is in a lake instead of on a road circling the lake, for example. This imprecision does not hinder the user experience, however, because the large circles that refine over time communicate that accuracy is not guaranteed. Your design should take into account this variable precision, and should provide users with a clear understanding of the reliability of location data.

Setting the distanceFilter property tells the location manager to change the granularity of its polling and to only notify its delegate of changes in location when the device has traveled at least as far as the filter. This can help mitigate battery drainage, but the use of a distance filter isn’t without power consumption.

In most cases, developers will need to retrieve location at least once and within certain accuracy tolerances. There is no property for the CLLocationManager class that can state an acceptable range of accuracy that, when reached, should stop polling. In addition, Core Location will cache the last known location of a device, and in most cases, the cached value will be the first reported location. This helps to improve the user experience by supplying an application with a relevant starting point for the update request. Each CLLocation instance has a timestamp property. It’s important to check the timestamp for all location objects returned by a location manager, because they are often returned from cache or reported out of order as a side effect of the mechanism that resolves the location of a device. Location-aware applications that report an outdated location from cache will seem defective and frustrate users:

// Get the timestamp of a CLLocation instance



- (void)locationManager:(CLLocationManager *)manager

didUpdateToLocation:(CLLocation *)newLocation

fromLocation:(CLLocation *)oldLocation

{

    NSDate *locationTimeStamp = newLocation.timestamp;

    NSTimeInterval delta = [locationTimeStamp timeIntervalSinceNow];

    NSLog(@"The location timestamp interval was %d seconds.", delta);

}
Programming the iPhone User Experience

Learn more about this topic from Programming the iPhone User Experience.

This practical book provides you with a hands-on, example-driven tour of Apple's user interface toolkit, UIKit, and some common design patterns for creating gestural interfaces and multi-touch navigation for the iPhone and iPod Touch. You'll learn how to build applications with Apple's Cocoa Touch frameworks that put the needs of mobile users front and center.

See what you'll learn


Tags:
0 Subscribe


1 Reply

 : May 25 2010 12:40 PM
Very helpful post! You mentioned a couple of details that caused me some problems when I was getting started.

1). If the user refuses to grant your App access to location information, this is communicated to the App via the kCLErrorDenied error. Upon receiving such an error, the app should stop the location service. If an App requires access to location services to operate correctly, common practice is to explain the need to the user and prompt them to close and relaunch the app.

2). If an App requires very precise position information, the developer need to realize that this may take a long while (and in some instances, may never converge). With this in mind, an App should have a reasonable timeout value or a means of allowing the user to give up. Waiting indefinitely for the position to converge will be viewed as a hang by the end user.