我正在尝试构建一个 iPhone 应用程序,它需要我使用 Core Location 始终跟踪用户的位置。我正在使用 startMonitoringSignificantLocationChanges 以便它在后台更新,因为准确性并不像每当发生重大变化时更新那么重要。
目前我向 Web 服务发出 HTTP 请求以更新位置。这在我运行应用程序时非常有效——我的位置在我存储位置数据的 MySQL 数据库中得到更新。但是当应用程序进入后台时——我可以在手机的右上角看到位置服务图标仍在运行,但当我返回查看数据库时,它根本没有更新我的位置。我通过开车穿过城镇来对此进行了测试,一种方式是在应用程序运行的情况下,另一种方式是在后台运行应用程序。
来自 Apple 的文档:
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.
这个“处理位置数据的少量时间”到底有多长?而且是只是不建议查询网络,还是那个时候不能查询网络?有没有更好的方法来跟踪多个不同用户的位置,即使应用程序在后台运行也是如此?
最佳答案
你应该看看后台任务。
当 Apple 说 处理位置数据需要少量时间
时,你不应该真的依赖于 locationManager:didUpdateToLocation:fromLocation:
方法有任何处理时间回来。假设您在单独的线程中异步运行 HTTP 请求,您可能没有足够的时间在应用程序暂停之前完成它。
UIBackgroundTasks 让您可以在后台请求操作系统额外的处理时间。发出 HTTP 请求可能就是这样一项任务。时间限制为 10 分钟,但不能保证您有这么多时间。
在您的位置回调中,您应该为您的请求定义一个新的后台任务。如果操作系统决定不能给您更多的处理时间,则随时会触发过期处理程序 block 。
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// Start your request here
UIBackgroundTaskIdentifier backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
backgroundTask = UIBackgroundTaskInvalid;
// Cancel your request here
}];
}
当请求完成时,您应该告诉应用程序任务已完成:
- (void)requestFinished:(id)request {
[[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
backgroundTask = UIBackgroundTaskInvalid;
}
在此示例中,我没有考虑到您可能会在请求完成之前收到多个位置回调。如果发生这种情况,您需要在开始新请求之前取消该请求和当前后台任务,或者为每个请求创建一个单独的后台任务。
另一种方法是在位置回调方法中在主线程上同步运行 HTTP 请求,但出于多种原因这样做是一件坏事,例如如果用户打开应用程序会锁定界面当请求正在运行时。
关于ios - 如何在 iOS 应用程序中在线更新后台位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11329992/