繁体   English   中英

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

[英]How to update location in background online in an iOS app?

我正在尝试构建一个iPhone应用程序,要求我使用Core Location随时跟踪用户的位置。 我正在使用startMonitoringSignificantLocationChanges,以便它在后台更新,因为准确性不如每当有重大变化时更新那么重要。

目前,我向Web服务发出HTTP请求以更新位置。 这在我运行应用程序时非常有效 - 我的位置在MySQL数据库中更新我正在存储位置数据。但是当应用程序进入后台时 - 我可以在手机的右上角看到位置服务图标仍在运行,但当我回去查看数据库时,它根本没有更新我的位置。 我通过驾车穿越城镇,在应用程序运行的一种方式,以及在后台使用应用程序的一种方式测试了这一点。

来自Apple的文档:

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

这个“处理位置数据的时间有多短”到底有多长? 是不是建议不要查询网络,还是不可能在那段时间查询网络? 即使应用程序在后台,有没有更好的方法来跟踪几个不同用户的位置?

你应该看一下后台任务。

当Apple说small amount of time to process location data ,你不应该真正依赖于在locationManager:didUpdateToLocation:fromLocation:之后获取任何处理时间locationManager:didUpdateToLocation:fromLocation:方法已经返回。 假设您在一个单独的线程中异步运行HTTP请求,您可能没有足够的时间在应用程序暂停之前完成它。

UIBackgroundTasks让您在后台询问操作系统的额外处理时间。 发出HTTP请求可能是一项任务。 时间限制是10分钟,但不能保证你得到这么多时间。

在您的位置回调中,您应该为您的请求定义新的后台任务。 如果操作系统确定它不能再为您提供处理时间,则会随时触发到期处理程序块。

- (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请求,但由于多种原因这将是一件坏事,例如,如果用户在请求时打开应用程序,则锁定界面在跑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM