获取 iOS 应用程序的位置更新,即使在暂停时也是如此

Get Location Updates for iOS App Even when Suspended

2014 年初,Apple 已将 iOS 7.0 更新为 7.1,以便即使应用程序在前台和后台未处于活动状态时也允许位置更新。我们该怎么做?

我读过一些文章,比如Apple's iOS 7.1 will fix a geolocation bug。但 Apple 没有提供太多与此相关的信息,也没有提供任何关于如何获取位置更新的示例代码,即使应用程序是 killed/terminated/suspended。

我已阅读 Release Notes for iOS 7.1。我也找不到与此相关的任何内容。

那么,即使应用已暂停,我们如何实际获取 iOS 7 和 8 的位置更新?

通过试验 Core Location 框架,经过几个月的反复试验,我找到了即使应用程序处于 killed/suspended 也能获取位置更新的解决方案。它适用于 iOS 7 和 8。

解决方法如下:-

如果您的应用程序是基于位置的移动应用程序,需要在设备位置发生重大变化时监控设备的位置,则 iOS 会在设备移动时 return 为您提供一些位置坐标距离最后已知位置超过 500 米。是的,即使应用 killed/suspended 由用户或 iOS 本身,您仍然可以获得位置更新。

因此,为了让 locationManager 即使在应用 killed/suspended 时也能获取位置更新,您必须使用方法 startMonitoringSignificantLocationChanges,不能使用 startUpdatingLocation .

当iOS想要return将位置更新到应用程序时,它会帮助您重新启动应用程序和return一键UIApplicationLaunchOptionsLocationKey到应用程序委托方法 didFinishLaunchingWithOptions.

关键UIApplicationLaunchOptionsLocationKey非常重要,你必须知道如何处理它。当您收到密钥时,您必须创建一个新的 locationManager 实例,您将在 locationManager 委托方法 didUpdateLocations.

上获得位置更新

这里是示例代码:-

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    self.shareModel = [LocationShareModel sharedModel];

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) { 
      self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init];
      self.shareModel.anotherLocationManager.delegate = self;
      self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
      self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation;

      if(IS_OS_8_OR_LATER) {
        [self.shareModel.anotherLocationManager requestAlwaysAuthorization];
      }

     [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];   

    }    
        return YES;
 }

除了 didFinishLaunchingWithOptions 方法之外,我还在应用程序处于活动状态时创建了 locationManager 实例。以下是一些代码示例:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [self.shareModel.anotherLocationManager stopMonitoringSignificantLocationChanges];

    if(IS_OS_8_OR_LATER) {
        [self.shareModel.anotherLocationManager requestAlwaysAuthorization];
    }

    [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    if(self.shareModel.anotherLocationManager)
        [self.shareModel.anotherLocationManager stopMonitoringSignificantLocationChanges];

    self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init];
    self.shareModel.anotherLocationManager.delegate = self;
    self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation;

    if(IS_OS_8_OR_LATER) {
        [self.shareModel.anotherLocationManager requestAlwaysAuthorization];
    }

    [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
}

我写了一篇文章,详细解释了如何获取 iOS 7 和 8 的位置更新,即使应用程序是 killed/suspended。我还在 GitHub 上上传了完整的源代码以及有关如何测试此解决方案的步骤。

请访问以下网址了解更多信息:-

  1. Getting Location Updates for iOS 7 and 8 when the App is Killed/Terminated/Suspended
  2. Source Code on GitHub - Get the Location Updates Even when the iOS mobile apps is Suspended/Terminated/Killed
locationManager = [[CLLocationManager alloc] init];
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)


if(IS_OS_8_OR_LATER)
{
    [locationManager requestWhenInUseAuthorization];
}

locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; //whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;

[locationManager startUpdatingLocation];

该代码用户位置仅更新前台应用 运行ning 但不更新后台 运行

[locationManager requestWhenInUseAuthorization];