ios - 如何在 iOS 应用程序中在线更新后台位置?

标签 ios core-location

我正在尝试构建一个 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/

相关文章:

ios - 在 iphone 中从另一个安装/更新应用程序

iOS Swift viewForHeaderInSection 未被调用

ios - CLLocation distanceFromLocation : returns zero on iOS 9. 是bug吗?

ios - 如何将 CoreLocation 坐标转换为字符串?

ios - 如何快速将图像旋转到特定的纬度和经度?

ios - 如何将变量的值设置为从 Alamofire 收到的数据?

ios - 以编程方式添加的 UITextField - 键盘导致应用程序在第一次按键时崩溃 - Swift

ios - OpenGLES : render buffer parameters in landscape orientation

iphone - iOS CoreLocation 仅在美国无法通过 3G 运行

ios - 检测用户是否在家