您的位置:首页 > 移动开发 > IOS开发

[iOS开发站在巨人肩膀上]之 iOS 4 in Action - Using Location Monitoring Service

2011-09-05 00:04 543 查看
本文来源:http://www.codeproject.com/KB/books/iOS-4-in-Action.aspx

When an application needs to continue running in the background, these multitasking features are available on iOS 4:

Audio—The application can continue running and play audio to the user while in the background. The user can use the multitasking UI or the lock screen UI to remote control the audio play, pause,
fast-forward, and so on.
Location—The application can receive location updates to support a location-related task or navigation in the background, such as significant location change service and turn-by-turn directions.
VoIP—Allows the application to receive voice calls through the Internet while other applications are in the foreground.

In this article, we will build a demo application that tracks the location updates in the background.


Updating the UI when the Application Relaunches

The first step is to create an application to display the collected location data. First, open Xcode and create a project using a navigation-based application template in the iOS application projects.
Name it Locations. In this application, we will use a table view to display all the new location updates from the location service running in the background.
The application’s view controller needs to update the user interface when the location is restarted from the background state.
Inside the RootViewConroller.h file, define an array
locationData
and use it as
table view’s data source, as shown in the following listing. Then, in the RootViewController.m file, display the location data on the table view. Keep in mind that the table view needs to reload the data when the application is restarted from the
background.


Listing 1 RootViewController’s header file and implementation file


Collapse | Copy
Code
#import <UIKit/UIKit.h>
@interface RootViewController : UITableViewController {
NSArray *locationData;
}
@property (nonatomic, retain) NSArray *locationData;
@end

#import "RootViewController.h"
@implementation RootViewController
@synthesizelocationData;

- (void)updateUI {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.locationData = [defaults objectForKey:@"kLocationData"];
[self.tableView reloadData];
}

- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Locations";
[self updateUI];
NSNotificationCenter *notifcenter = [NSNotificationCenter defaultCenter];
[notifcenter addObserver:self selector:@selector(updateUI) name:UIApplicationWillEnterForegroundNotification object:nil];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [locationData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [locationData objectAtIndex:indexPath.row];
return cell;
}
- (void)dealloc {
[locationData release];
[super dealloc];
}
@end

When the table view controller gets loaded, the
locationData
array will fetch the data
stored with
NSUserDefaults
, then update the table view based on the
locationData
array.
The notification center will observe the event when the application resumes from the background state and reload the table view’s data.
Now we have the table view ready to display the location data. Next, let’s look at how to get the location updates from the Core Location framework with the significant location update service.


Enabling Significant Location Change Service

In this part, we will add the significant location change service to our application locations. First, we add the Core Location framework to the project and include the core location header in
the app delegate file. Then, let’s add the Core Location Manager to the app delegate as an instance variable:
CLLocationManager *locationManager
. Now,
we will add changes from the following listing to the app delegate implementation file to enable the location monitoring service when the app launches.


Listing 2 Implementing Location Updates in the Background


Collapse | Copy
Code
#import "LocationsAppDelegate.h"
#import "RootViewController.h"

@implementation LocationsAppDelegate
@synthesize window;
@synthesize navigationController;

-(void)initLocationManager {                         #1
if (locationManager == nil) {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startMonitoringSignificantLocationChanges];
}
}
- (void)saveCurrentData:(NSString *)newData {               #2
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *savedData = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"kLocationData"]];
[savedData addObject:newData];
[defaults setObject:savedData forKey:@"kLocationData"];
[savedData release];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (![CLLocationManager significantLocationChangeMonitoringAvailable]) #3
{UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Sorry" message:@"Your device won't support the significant location change." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
return YES;                                   #3
}                                             #3
[self initLocationManager];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {                                        #4
NSString *locationData = [NSString stringWithFormat:@"%.6f, %.6f",newLocation.coordinate.latitude, newLocation.coordinate.longitude];
[self saveCurrentData:locationData];
}                                                  #4

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {                         #5
NSString *errorData = [NSString stringWithFormat:@"%@",[error localizedDescription]];
NSLog(@"%@", errorData);                              #5
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[locationManager release];
[navigationControllerrelease];
[window release];
[super dealloc];
}

@end

#1 Starts location service

#2 Stores data

#3 Tests if location service is available

#4 Updates location data

#5 Error handling

Inside the application delegate, we use the Core Location Manager to monitor the significant location change. When the application first launches, we call method
initLocationManager
(#1)
to initialize the location manager and start the significant location update service. In order to make sure the location service is actually available on this device, we use method
significantLocationChangeMonitoringAvailable
(#3)
to test the availability and, if not possible, to use the location update service on this device, we give user an alert.
Once the new location is available, the location manager delegate method is called (#4). We need to store the new location data using
NSDefaults
in
method
saveCurrentData
(#2). That’s how the table view can get all the new location updates from the application delegate.
In case an error occurs during location updating, the location manager calls the delegate method (#5). We can read out the error message inside the Console Window under Xcode.
You need to test this application on your iPhone or iPad with 3G since the simulator won’t support the location change service. Build and run this application on the device. Quit the application
to let the location service run in the background.
The locations application will continue receiving updates in the background and, once it’s relaunched, you can track all the places you’ve been to. Notice that, even if the application is suspended
in the background or the application is not running at all, the location service is running. You can tell by the indicator on the status bar of your iPhone or iPad 3G, as shown in figure 1.



Figure 1 Significant location updates application running in the background
You can combine this significant location updates service and notify user with local notifications. The region-based location monitoring service works exactly like the significant location updates
service. You can define which region to monitor; when the user enters that specific region, the application will receive the location update through core location delegate methods. The system will wake up the application even if the application is not running
or is suspended.


Summary

In this article, we dug into the multitasking topic and built the location tracking application with background significant location updates.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: