ios 终止/暂停时显着更改位置 API 的行为?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3421242/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Behaviour for significant change location API when terminated/suspended?
提问by RedBlueThing
This is the section from the CLLocationManagerdocumentation describing the app behavior with startMonitoringSignificantLocationChanges:
这是CLLocationManager文档中描述startMonitoringSignificantLocationChanges的应用程序行为的部分:
If you start this service and your application is subsequently terminated, the system automatically relaunches the application into the background if a new event arrives. In such a case, the options dictionary passed to the application:didFinishLaunchingWithOptions: method of your application delegate contains the key UIApplicationLaunchOptionsLocationKey to indicate that your application was launched because of a location event. Upon relaunch, you must still configure a location manager object and call this method to continue receiving location events. When you restart location services, the current event is delivered to your delegate immediately. In addition, the location property of your location manager object is populated with the most recent location object even before you start location services.
如果您启动此服务并且您的应用程序随后被终止,则系统会在新事件到达时自动将应用程序重新启动到后台。在这种情况下,传递给 application:didFinishLaunchingWithOptions: 应用程序委托的方法的选项字典包含键 UIApplicationLaunchOptionsLocationKey 以指示您的应用程序由于位置事件而启动。重新启动后,您仍必须配置位置管理器对象并调用此方法以继续接收位置事件。当您重新启动定位服务时,当前事件会立即传递给您的委托。此外,即使在您启动位置服务之前,您的位置管理器对象的位置属性也会填充最新的位置对象。
So my understanding is that if your app terminates (and I assume if you don't call stopMonitoringSignificantLocationChangesfrom applicationWillTerminate) you will get woken up with a UIApplicationLaunchOptionsLocationKeyparameter to application:didFinishLaunchingWithOptions. At that point you create your CLLocationManager, call startMonitoringSignificantLocationChangesand do your background location processing for a limited time. So I am fine with this bit.
所以我的理解是,如果您的应用程序终止(我假设如果您不从applicationWillTerminate调用stopMonitoringSignificantLocationChanges),您将被一个UIApplicationLaunchOptionsLocationKey参数唤醒到application:didFinishLaunchingWithOptions。此时,您创建CLLocationManager,调用startMonitoringSignificantLocationChanges并在有限的时间内进行后台位置处理。所以我对这一点很好。
The previous paragraph only talks about what happens when the app is terminated, it doesn't suggest what you do when the application is suspended. The documentation for didFinishLaunchingWithOptionssays:
上一段只讨论了应用程序终止时会发生什么,并没有建议您在应用程序暂停时做什么。didFinishLaunchingWithOptions的文档说:
The application tracks location updates in the background, was purged, and has now been relaunched. In this case, the dictionary contains a key indicating that the application was relaunched because of a new location event.
该应用程序在后台跟踪位置更新,已被清除,现在已重新启动。在这种情况下,字典包含一个键,指示应用程序由于新的位置事件而重新启动。
Suggesting that you will only receive this call when your app is launched (because of a location change) after you have been terminated.
建议您仅在您的应用程序启动时(由于位置更改)在您被终止后才会收到此调用。
However the paragraph on the Significant Change Servicein the Location Awareness Programming Guidehas the following to say:
但是,《位置感知编程指南》中有关重大更改服务的段落有以下内容:
If you leave this service running and your application is subsequently suspended or terminated, the service automatically wakes up your application when new location data arrives. At wake-up time, your application is put into the background and given a small amount of time to process the location data. Because your application is in the background, it should do minimal work and avoid any tasks (such as querying the network) that might prevent it from returning before the allocated time expires. If it does not, your application may be terminated.
如果您让此服务继续运行,而您的应用程序随后被挂起或终止,则该服务会在新位置数据到达时自动唤醒您的应用程序。在唤醒时,您的应用程序被置于后台并有少量时间来处理位置数据。因为您的应用程序在后台,它应该做最少的工作并避免任何可能阻止它在分配的时间到期之前返回的任务(例如查询网络)。如果没有,您的申请可能会被终止。
This suggests you are woken up with location data if your app has been suspended, but fails to mention how you are woken up:
这表明如果您的应用程序已暂停,您会被位置数据唤醒,但没有提及您是如何被唤醒的:
- Does the UIApplicationDelegateget a callback telling me that I am resuming from a suspended state into a background state?
- Does the location manager (that was freeze dried when the app was suspended) start receiving locationManager:didUpdateToLocation:fromLocationcallbacks?
- Do I just need to implement code in my didUpdateToLocationmessage which checks the application state and does minimal processing if in background mode?
- UIApplicationDelegate是否收到一个回调,告诉我我正在从挂起状态恢复到后台状态?
- 位置管理器(在应用程序暂停时被冻干)是否开始接收locationManager:didUpdateToLocation:fromLocation回调?
- 我是否只需要在我的didUpdateToLocation消息中实现代码来检查应用程序状态并在后台模式下进行最少的处理?
In the process of writing this up, I think I may have just answered my own question, but it would be great to have my understanding of this confirmed by someone more knowledgeable.
在写这篇文章的过程中,我想我可能刚刚回答了我自己的问题,但如果我的理解能得到更了解的人的证实,那就太好了。
采纳答案by RedBlueThing
Since I asked this question, I have done a fair bit of testing (mostly on the train between home and work) and have confirmed that the behaviour for suspended apps is as I suspected at the end of the question.
自从我问这个问题以来,我做了相当多的测试(主要是在回家和工作之间的火车上)并确认暂停应用程序的行为正如我在问题结束时所怀疑的那样。
That is, your suspended app is woken up, you don't receive any callbacks on your app delegate, instead you receive your location updates through your existing CLLocationManagerDelegate. You can detect that you are running in the background by checking the applicationState, and do limited work for the case where you are woken from a suspended state to do location processing.
也就是说,您暂停的应用程序被唤醒,您不会在应用程序委托上收到任何回调,而是通过现有的CLLocationManagerDelegate收到您的位置更新。您可以通过检查applicationState来检测您是否在后台运行,并在您从挂起状态唤醒进行位置处理的情况下做有限的工作。
[UIApplication sharedApplication].applicationState == UIApplicationStateBackground
I came to this conclusion with a location test harness that you are welcome to downloadand try out. It is a pretty simple app that allows you to turn on significant change and GPS change APIs through the UI and log all the responses that you get back.
我通过一个位置测试工具得出了这个结论,欢迎您下载并试用。这是一个非常简单的应用程序,允许您通过 UI 打开重大更改和 GPS 更改 API,并记录您返回的所有响应。
N.B.Point six in the previous answer is not correct. Freeze driedsuspended apps do receive CLLocationManagerDelegatecallbacks when they are woken up from a suspended state.
注意上一个答案中的第六点不正确。冻干挂起的应用程序在从挂起状态唤醒时确实会收到CLLocationManagerDelegate回调。
回答by Aaron
My understanding is as follows (I'm in the process of writing an application that relies on this API, but haven't completed this component enough to start testing):
我的理解如下(我正在编写一个依赖这个API的应用程序,但还没有完成这个组件,无法开始测试):
- Your application is run for the first time, you register to startMonitoringSignificantLocationChanges, and provide a callback function. While your application is running, it will call that callback whenever it receives a significant change.
- If your application is put to the background, UIApplication will receive applicationWillResignActive, followed by applicationDidEnterBackground.
- If your application is killed while it is suspended in the background, you will not be notified; however, if your application is killed while it is running (foreground or background to my knowledge), you will get a moment with applicationWillTerminate. You cannot request extra background time from this function.
Despite being killed in the background, the OS will relaunch your application. If your application is simply launched by the OS for a change, you will get a call to application didFinishLaunchingWithOptions:
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])
will help you determine if you've come back from a background location change.
- If, instead, you were currently running in the background, and your app is manually relaunched by the user, you will receive an applicationWillEnterForegroundfollowed by applicationDidBecomeActive.
Regardless of how it happened, when your application is relaunched (unless it was still running in the background as a result of a background task and said task had started monitoring changes), you need to explicitly tell it to startMonitoringSignificantLocationChangesagain because the callback is no longer attached after "freeze drying." And yes, you just need to implement code in didUpdateToLocation once you've re-attached a location handler of some kind once coming back from the suspended state.
- 您的应用程序是第一次运行,您注册到startMonitoringSignificantLocationChanges,并提供回调函数。当您的应用程序运行时,它会在收到重大更改时调用该回调。
- 如果您的应用程序被置于后台, UIApplication 将收到applicationWillResignActive,然后是applicationDidEnterBackground。
- 如果您的应用程序在后台暂停时被杀死,您将不会收到通知;但是,如果您的应用程序在运行时被终止(据我所知是前台或后台),您将有时间使用applicationWillTerminate。您不能从此函数请求额外的后台时间。
尽管在后台被杀死,操作系统仍将重新启动您的应用程序。如果您的应用程序只是由操作系统启动以进行更改,您将收到对应用程序 didFinishLaunchingWithOptions的调用:
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])
将帮助您确定您是否从后台位置更改回来。
- 相反,如果您当前正在后台运行,并且您的应用程序由用户手动重新启动,您将收到一个applicationWillEnterForeground后跟applicationDidBecomeActive。
不管它是如何发生的,当您的应用程序重新启动时(除非它由于后台任务而仍在后台运行并且所述任务已开始监视更改),您需要明确告诉它再次startMonitoringSignificantLocationChanges因为回调是没有“冷冻干燥”后附着时间更长。是的,一旦您从挂起状态返回后重新附加了某种位置处理程序,您只需要在 didUpdateToLocation 中实现代码。
This is what I'm going on with my code development right now. As I mentioned before, I'm not quite ready to test this on a device so I can't tell if I've interpreted everything correctly, so commenters, please feel free to correct me (though I've done substantial reading on the topic).
这就是我现在正在进行的代码开发。正如我之前提到的,我还没有准备好在设备上进行测试,所以我无法判断我是否正确解释了所有内容,所以评论者请随时纠正我(尽管我已经对话题)。
Oh, and if by some stroke of bad luck, you release an app that does what I want mine to do, I might cry :)
哦,如果运气不好,你发布了一个应用程序来做我想让我做的事情,我可能会哭:)
Good luck!
祝你好运!
回答by Anshu
If the application is evoked from suspended state as a result of location change application will launch in background state.
如果应用程序由于位置更改而从挂起状态唤醒,应用程序将在后台状态启动。
All the objects will be live and you will recieve location update in the existing delegate.
所有对象都将处于活动状态,您将在现有委托中收到位置更新。