这是使用CLLocationManager描述应用行为的startMonitoringSignificantLocationChanges文档中的部分:
如果你开始这项服务和你的 随后申请 系统自动终止 将应用程序重新启动到 如果新事件到来,则为背景。在 这样的情况下,选项字典 传递给了 应用中:didFinishLaunchingWithOptions: 应用程序委托的方法 包含密钥 UIApplicationLaunchOptionsLocationKey 表明你的申请是 由于位置事件而启动。 重新启动后,您仍然必须 配置位置管理器对象 并调用此方法继续 接收位置事件。当你 重启位置服务,目前 活动将传递给您的代表 立即。另外,位置 您的位置经理的财产 对象填充最多 最近的位置对象甚至在你之前 开始定位服务。
所以我的理解是,如果您的应用终止(并假设您未从stopMonitoringSignificantLocationChanges致电applicationWillTerminate),您将会被UIApplicationLaunchOptionsLocationKey参数唤醒{{} 3}}。此时,您可以创建application:didFinishLaunchingWithOptions,致电CLLocationManager并为startMonitoringSignificantLocationChanges进行后台位置处理。所以我对此很好。
前一段只谈到应用程序终止时会发生什么,它不会建议您在应用程序暂停时执行的操作。 limited time的文档说:
应用程序跟踪位置 在后台更新,被清除, 现在又重新推出了。在这 例如,字典包含一个键 表明该应用程序是 由于新的位置而重新启动 事件
建议您在终止应用后(由于位置更改)启动应用后才会收到此来电。
然而,didFinishLaunchingWithOptions中Significant Change Service上的段落有如下说法:
如果您正在运行此服务 随后你的申请 暂停或终止,该服务 自动唤醒你的 应用新位置数据时 到达。在醒来的时候,你的 应用程序被放到后台 并给予少量时间 处理位置数据。因为 你的申请是在后台, 它应该做最小的工作,避免 任何任务(例如查询 网络)可能会阻止它 在分配的时间之前返回 到期。如果没有,你的 申请可能会被终止。
这表示如果您的应用已被暂停,您会被位置数据唤醒,但未提及您是如何被唤醒的:
在写这篇文章的过程中,我想我可能刚刚回答了我自己的问题,但是如果有更多知识渊博的人对我的理解得到证实那就太棒了。
答案 0 :(得分:80)
自从我提出这个问题以来,我已经做了一些测试(主要是在家庭和工作之间的火车上),并确认暂停应用程序的行为是我在问题结束时所怀疑的。
也就是说,您暂停的应用已被唤醒,您的应用代表未收到任何回调,而是通过现有的CLLocationManagerDelegate收到您的位置信息更新。您可以通过检查 applicationState 来检测您在后台运行,并针对您从暂停状态唤醒以进行位置处理的情况进行有限的工作。
[UIApplication sharedApplication].applicationState == UIApplicationStateBackground
我通过位置测试工具得出了这个结论,欢迎您download尝试一下。这是一个非常简单的应用程序,允许您通过用户界面打开重大更改和GPS更改API,并记录您收到的所有响应。
N.B。上一个答案中的第六点不正确。 冻结暂停的应用在从暂停状态唤醒时会收到 CLLocationManagerDelegate 回调。
答案 1 :(得分:25)
我的理解如下(我正在编写依赖于此API的应用程序,但尚未完成此组件以便开始测试):
尽管在后台被杀,操作系统仍将重新启动您的应用程序。如果您的应用程序仅由操作系统启动以进行更改,您将接到应用程序didFinishLaunchingWithOptions 的调用:
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])
将帮助您确定是否从更改后台位置返回。
这就是我现在正在进行的代码开发。正如我之前提到的,我还没准备好在设备上测试这个,所以我不知道我是否正确解释了所有内容,所以评论者请随时纠正我(尽管我已经对主题)。
哦,如果运气不好,你发布的应用程序可以做我想做的事情,我可能会哭:)
祝你好运!答案 2 :(得分:1)
如果应用程序因位置更改而处于挂起状态,则应用程序将以后台状态启动。
所有对象都将生效,您将在现有代表中接收位置更新。
答案 3 :(得分:0)
所以我有一个关于应用终止时间的重要说明:
对于某些可以在后台启动应用程序并且稍后需要接收处理该启动的回调的 API,可能需要设置 delegate
对象。 >
因此,如果您因为位置跟踪而获得 应用程序启动(即从终止状态,而不是暂停状态),那么您的 locationManager 委托回调将不会被调用,除非您在 { {1}}。更准确地说,在设置委托之前,您不会收到任何委托回调。
didFinishLaunching
认为应用神奇地知道委托对象是什么是不正确的。它不会保留这些信息。
解决方案:
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 的委托之前,您会错过任何回调。