终止/暂停时重要更改位置API的行为?

时间:2010-08-06 05:37:50

标签: ios core-location cllocationmanager uiapplicationdelegate

这是使用CLLocationManager描述应用行为的startMonitoringSignificantLocationChanges文档中的部分:

  

如果你开始这项服务和你的   随后申请   系统自动终止   将应用程序重新启动到   如果新事件到来,则为背景。在   这样的情况下,选项字典   传递给了   应用中:didFinishLaunchingWithOptions:   应用程序委托的方法   包含密钥   UIApplicationLaunchOptionsLocationKey   表明你的申请是   由于位置事件而启动。   重新启动后,您仍然必须   配置位置管理器对象   并调用此方法继续   接收位置事件。当你   重启位置服务,目前   活动将传递给您的代表   立即。另外,位置   您的位置经理的财产   对象填充最多   最近的位置对象甚至在你之前   开始定位服务。

所以我的理解是,如果您的应用终止(并假设您未从stopMonitoringSignificantLocationChanges致电applicationWillTerminate),您将会被UIApplicationLaunchOptionsLocationKey参数唤醒{{} 3}}。此时,您可以创建application:didFinishLaunchingWithOptions,致电CLLocationManager并为startMonitoringSignificantLocationChanges进行后台位置处理。所以我对此很好。

前一段只谈到应用程序终止时会发生什么,它不会建议您在应用程序暂停时执行的操作。 limited time的文档说:

  

应用程序跟踪位置   在后台更新,被清除,   现在又重新推出了。在这   例如,字典包含一个键   表明该应用程序是   由于新的位置而重新启动   事件

建议您在终止应用后(由于位置更改)启动应用后才会收到此来电。

然而,didFinishLaunchingWithOptionsSignificant Change Service上的段落有如下说法:

  

如果您正在运行此服务   随后你的申请   暂停或终止,该服务   自动唤醒你的   应用新位置数据时   到达。在醒来的时候,你的   应用程序被放到后台   并给予少量时间   处理位置数据。因为   你的申请是在后台,   它应该做最小的工作,避免   任何任务(例如查询   网络)可能会阻止它   在分配的时间之前返回   到期。如果没有,你的   申请可能会被终止。

这表示如果您的应用已被暂停,您会被位置数据唤醒,但未提及您是如何被唤醒的:

在写这篇文章的过程中,我想我可能刚刚回答了我自己的问题,但是如果有更多知识渊博的人对我的理解得到证实那就太棒了。

4 个答案:

答案 0 :(得分:80)

自从我提出这个问题以来,我已经做了一些测试(主要是在家庭和工作之间的火车上),并确认暂停应用程序的行为是我在问题结束时所怀疑的。

也就是说,您暂停的应用已被唤醒,您的应用代表未收到任何回调,而是通过现有的CLLocationManagerDelegate收到您的位置信息更新。您可以通过检查 applicationState 来检测您在后台运行,并针对您从暂停状态唤醒以进行位置处理的情况进行有限的工作。

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

我通过位置测试工具得出了这个结论,欢迎您download尝试一下。这是一个非常简单的应用程序,允许您通过用户界面打开重大更改和GPS更改API,并记录您收到的所有响应。

N.B。上一个答案中的第六点不正确。 冻结暂停的应用在从暂停状态唤醒时会收到 CLLocationManagerDelegate 回调。

答案 1 :(得分:25)

我的理解如下(我正在编写依赖于此API的应用程序,但尚未完成此组件以便开始测试):

  1. 您的应用程序首次运行,您注册 startMonitoringSignificantLocationChanges ,并提供回调函数。当您的应用程序正在运行时,它会在收到重大更改时调用该回调。
  2. 如果您的申请被置于后台,UIApplication将收到 applicationWillResignActive ,然后是 applicationDidEnterBackground
  3. 如果您的申请在后台暂停时被杀,您将不会收到通知;但是,如果您的应用程序在运行时被终止(前景或背景知识),您将获得 applicationWillTerminate 的时刻。您无法通过此功能请求额外的背景时间。
  4. 尽管在后台被杀,操作系统仍将重新启动您的应用程序。如果您的应用程序仅由操作系统启动以进行更改,您将接到应用程序didFinishLaunchingWithOptions 的调用:

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])
    

    将帮助您确定是否从更改后台位置返回。

  5. 如果您当前正在后台运行,并且您的应用由用户手动重新启动,您将收到 applicationWillEnterForeground ,然后是 applicationDidBecomeActive
  6. 无论发生的情况如何,当您的应用程序重新启动时(除非由于后台任务仍然在后台运行并且所述任务已开始监视更改),您需要明确告诉它< strong> startMonitoringSignificantLocationChanges ,因为“冻干”后不再附加回调。是的,一旦从挂起状态返回,您只需重新附加某种位置处理程序,就需要在didUpdateToLocation中实现代码。
  7. 这就是我现在正在进行的代码开发。正如我之前提到的,我还没准备好在设备上测试这个,所以我不知道我是否正确解释了所有内容,所以评论者请随时纠正我(尽管我已经对主题)。

    哦,如果运气不好,你发布的应用程序可以做我想做的事情,我可能会哭:)

    祝你好运!

答案 2 :(得分:1)

如果应用程序因位置更改而处于挂起状态,则应用程序将以后台状态启动。

所有对象都将生效,您将在现有代表中接收位置更新。

答案 3 :(得分:0)

所以我有一个关于应用终止时间的重要说明:

对于某些可以在后台启动应用程序并且稍后需要接收处理该启动的回调的 API,可能需要设置 delegate 对象。 >

因此,如果您因为位置跟踪而获得 应用程序启动(即从终止状态,而不是暂停状态),那么您的 locationManager 委托回调将不会被调用,除非您在 { {1}}。更准确地说,在设置委托之前,您不会收到任何委托回调。

  1. 因此,如果您在应用启动后在 ABC 视图控制器中执行关注
didFinishLaunching
  1. 然后应用被终止
  2. 然后应用程序是由于后台位置更改而导致的位置
  3. 在您将应用置于前台并打开 ABC 视图控制器之前,您不会收到回调

认为应用神奇地知道委托对象是什么是不正确的。它不会保留这些信息。

解决方案:

let manager = CLLocationManager()
manager.delegate = self

我为一个完全不相关的 API 发现了这一点:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
   let myLocationManager = CLLocationManager()
   myLocationManager.delegate = self
}

也就是说,如果您没有在 AppLaunch 之前设置您的委托,那么您会错过用户与应用终止后立即发生的通知的交互。更准确地说,在设置 userNotification 的委托之前,您会错过任何回调。