65.9K
CodeProject 正在变化。 阅读更多。
Home

iOS 4 实战 - 使用位置监控服务

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (2投票s)

2011 年 5 月 20 日

CPOL

5分钟阅读

viewsIcon

21242

《iOS 4 实战》的章节摘录

image002.jpg iOS 4 实战
开发 iPhone 和 iPad 应用

作者:Jocelyn Harrington, Brandon Trebitowski, Christopher Allen, and Shannon Appelcline

应用程序可以接收位置更新,以支持后台的位置相关任务或导航,例如显著位置变更服务和逐向导航。在本文中,基于《iOS 4 实战》第 22 章的内容,作者构建了一个跟踪后台位置更新的演示应用程序。

下次购买可享 35% 的折扣,在 www.manning.com 结账时使用促销代码 jharrington2235

您可能还对以下内容感兴趣…

当应用程序需要在后台继续运行时,iOS 4 提供了这些多任务处理功能:

  • 音频 - 应用程序可以在后台继续运行并向用户播放音频。用户可以使用多任务处理 UI 或锁屏 UI 来远程控制音频的播放、暂停、快进等。
  • 位置 - 应用程序可以接收位置更新,以支持后台的位置相关任务或导航,例如显著位置变更服务和逐向导航。
  • VoIP - 允许应用程序在其他应用程序处于前台时通过互联网接收语音通话。

在本文中,我们将构建一个跟踪后台位置更新的演示应用程序。

应用程序重新启动时更新 UI

第一步是创建一个应用程序来显示收集的位置数据。首先,打开 Xcode 并使用 iOS 应用程序项目中的基于导航的应用程序模板创建一个项目。将其命名为 Locations。在此应用程序中,我们将使用表视图来显示在后台运行的位置服务的所有新的位置更新。

当应用程序从后台状态重新启动时,应用程序的视图控制器需要更新用户界面。

RootViewConroller.h 文件中,定义一个数组 locationData 并将其用作表视图的数据源,如以下列表所示。然后,在 RootViewController.m 文件中,在表视图上显示位置数据。请记住,当应用程序从后台重新启动时,表视图需要重新加载数据。

列表 1 RootViewController 的头文件和实现文件

#import <UIKit/UIKit.h>
@interface RootViewController : UITableViewController {
     NSArray *locationData;
}
@property (nonatomic, retain) NSArray *locationData;
@end                                   
 
#import "RootViewController.h"               
@implementation RootViewController
@synthesize locationData;
 
- (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

当表视图控制器加载时,locationData 数组将获取使用 NSUserDefaults 存储的数据,然后根据 locationData 数组更新表视图。通知中心将观察应用程序从后台状态恢复时的事件并重新加载表视图的数据。

现在,我们已经准备好表视图来显示位置数据。接下来,让我们看看如何使用显著位置更新服务从 Core Location 框架获取位置更新。

启用显著位置变更服务

在本部分中,我们将向我们的应用程序 Locations 添加显著位置变更服务。首先,我们将 Core Location 框架添加到项目中,并将 core location 头文件包含在 app delegate 文件中。然后,让我们将 Core Location Manager 添加到 app delegate 中作为实例变量:CLLocationManager *locationManager。现在,我们将添加以下列表中的更改到 app delegate 实现文件中,以便在应用程序启动时启用位置监控服务。

列表 2 在后台实现位置更新

#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 启动位置服务
#2 存储数据
#3 测试位置服务是否可用
#4 更新位置数据
#5 错误处理

在应用程序委托中,我们使用 Core Location Manager 来监控显著位置变更。当应用程序首次启动时,我们调用 initLocationManager 方法(#1)来初始化位置管理器并启动显著位置更新服务。为了确保该设备上确实可用位置服务,我们使用 significantLocationChangeMonitoringAvailable 方法(#3)来测试可用性,如果无法在此设备上使用位置更新服务,我们将向用户显示一个警告。

一旦新的位置可用,就会调用位置管理器委托方法(#4)。我们需要在 saveCurrentData 方法(#2)中使用 NSDefaults 来存储新的位置数据。这样,表视图就可以从应用程序委托获取所有新的位置更新了。

万一在位置更新过程中发生错误,位置管理器会调用委托方法(#5)。我们可以在 Xcode 下的 Console Window 中读取错误消息。

您需要在具有 3G 功能的 iPhone 或 iPad 上测试此应用程序,因为模拟器不支持位置变更服务。在设备上构建并运行此应用程序。退出应用程序,让位置服务在后台运行。

Locations 应用程序将继续在后台接收更新,一旦重新启动,您就可以跟踪您去过的所有地方。请注意,即使应用程序在后台挂起或根本未运行,位置服务仍在运行。您可以通过 iPhone 或 iPad 3G 的状态栏上的指示器来判断,如图 1 所示。

image003.gif

图 1 显著位置更新应用程序在后台运行

您可以将此显著位置更新服务与本地通知结合使用,并通知用户。基于区域的位置监控服务的工作方式与显著位置更新服务完全相同。您可以定义要监控的区域;当用户进入特定区域时,应用程序将通过 core location 委托方法接收位置更新。即使应用程序未运行或已挂起,系统也会唤醒应用程序。

摘要

在本文中,我们深入探讨了多任务处理主题,并使用后台显著位置更新构建了位置跟踪应用程序。

以下是您可能感兴趣的其他 Manning 图书:

image004.jpg

iPhone Objective-C
作者:Christopher K. Fairbairn 和 Collin Ruffenach

image005.jpg

iPhone 开发实践
Bear P. Cahill

image006.jpg

Android 解锁(第二版)
作者:W. Frank Ableson 和 Robi Sen

最后更新:2011 年 5 月 18 日

© . All rights reserved.