应用程序在后台运行一段时间后,位置跟踪会停止
我创建了一个简单的应用程序,它可以跟踪用户位置,并在每次更新位置时创建本地通知。
我启用了下面的背景模式,
let locationManager = CLLocationManager() open override func viewDidLoad() { locationManager.delegate = self; locationManager.desiredAccuracy = kCLLocationAccuracyBest; locationManager.distanceFilter = 10 locationManager.allowsBackgroundLocationUpdates = true locationManager.startUpdatingLocation() } open func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { let notification = UILocalNotification() notification.alertBody = "location updated" notification.fireDate = Date() UIApplication.shared.scheduleLocalNotification(notification) }
我为NSLocationAlwaysUsageDescription
设置字符串并请求许可。 第一次加载应用时始终使用的用户授予权限。
它在应用程序处于前台时运行良好,当它仍然在后台仍然工作时至少在5-40分钟的时间范围内,可以通过电池或其他打开的应用程序进行更改。
问题是为什么它停止工作,它不会继续工作?
我从未在Apple文档中看到时间限制。
当应用移动到后台时切换到重要的位置更新。 如果应用程序无限期地在后台保持活动状态,iOS将卸载该应用程序。
locationManager.pausesLocationUpdatesAutomatically = false
在搜索引用(谈论任何限制)后,我认为Apple Core Location Best Practicesvideo会话可能很有用! 在06:53
谈论背景中的标准位置:
此外,Core Location不会采取任何措施来确保您的应用程序继续运行,因此如果您因某些原因而运行后台并且您决定启动一个位置会话,您可能会获得一些更新,但您可能会在收到之前被暂停您希望收到的所有信息……
实际上,我之前遇到过这个问题, – 作为一种解决方法 – 核心位置用于跟踪用户的位置,以便对其位置执行无关的function – 这是上传文件 – 但是这种解决方法在iOS 9后无效已被释放; 我甚至发了一个提到这个问题的问题。
但是,如果您的目标是,您的情况似乎与我所面临的情况不同:
…每次更新位置时都会创建本地通知。
那么您可能需要遵循与用户通知框架集成的方法 – UNLocationNotificationTrigger :
用户必须达到的地理位置才能启用本地通知。
它也在video会话( 08:59
)中提到。
也许,这可能不是你想要的,但由于我们无法保证后台执行将继续运行,你可能 – 在某种程度上 – 找到一种方法将它集成到你的应用程序中以实现所需的function。
iOS 11更新:
您可能需要检查此答案以获取请求位置访问的正确方法。
由于它的声音,应用程序因内存限制而被杀死。 但是,当新位置可用时,应该重新启动它,如下所述: https : //developer.apple.com/documentation/uikit/uiapplicationlaunchoptionskey/1623101-location
您应该看到正在调用application(_:didFinishLaunchingWithOptions:)
,并且启动选项中应该存在’location’键。 然后,您可以重新创建消耗位置的任何内容并继续录制。
如果没有重新启动,那可能会让人感到内存不足。 检查应用程序的内存消耗,看看是否正在调用applicationDidReceiveMemoryWarning(_:)
。
降低准确性
设置位置管理器对象的desiredAccuracy
属性
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
您可以使用CLLocationAccuracy
常量之一
重要
默认情况下,iOS设备上的标准位置更新以最佳准确度运行。 更改这些设置以符合您应用的要求。 否则,您的应用程序将不必要地浪费能源。
自动暂停
将位置管理器对象的pausesLocationUpdatesAutomatically
属性设置为true
self.locationManager.pausesLocationUpdatesAutomatically = true
重要
对于具有使用中授权的应用,暂停到位置更新会终止对位置更改的访问,直到应用再次启动并能够重新启动这些更新。 如果您不希望位置更新完全停止,请考虑在应用移动到后台时禁用此属性并将位置精度更改为
kCLLocationAccuracyThreeKilometers
。 这样做可以让您以function友好的方式继续接收位置更新。
允许后台更新
将location Manager对象的allowsBackgroundLocationUpdates
属性设置为true
self.locationManager.allowsBackgroundLocationUpdates = true
想要在挂起时接收位置更新的应用必须在其应用的Info.plist文件中包含UIBackgroundModes键(具有位置值),并将此属性的值设置为true。 后台更新需要存在具有位置值的UIBackgroundModes键
指定活动类型
设置activityType
属性,让Core Location知道您的应用在给定时间执行的位置活动类型
self.locationManager.activityType = .automotiveNavigation
您可以使用其中一个CLActivityType
案例
推迟位置更新
在支持GPS设备的设备上,当您的应用在后台时,您可以让位置管理员推迟发布位置更新。 例如,跟踪用户在远足径上的位置的健身应用可以推迟更新,直到用户移动了特定距离或经过了特定时间段。
- 适用于iOS应用的能效指南 – 位置最佳实践
- GettingLocationWhenSuspended
我假设你没有实现后台任务。 你可以在这里阅读。
在上面的链接“实施长时间运行的任务”一节中没有。 3是你的情况,所以你可以在你的项目中使用后台位置更新是有效的,同样你也需要实现后台任务。
有三种方法可以跟踪用户位置(如上面链接“跟踪用户位置” ): –
- 仅限前台的位置服务(适用于您的情况)
- 重大改变位置服务( 推荐 ),但我认为它不适用于你的情况,因为你想每10米更新一次用户位置,它可以工作约500米,更多请看这里
- 后台位置服务(我认为你正在尝试这个),解决方案是添加后台任务。
下面是后台任务的示例,您可以根据自己的要求进行修改,自上次工作2小时起,它对我有用,我的应用程序仍在后台更新位置。
。
在您的AppDelegate类中,请更新以下function,然后在后台运行您的应用程序。
func applicationDidEnterBackground(_ application: UIApplication) { application.beginBackgroundTask(withName: "") {} }
以下是我的ViewController类
import UIKit import CoreLocation class ViewController: UIViewController, CLLocationManagerDelegate { let locationManager = CLLocationManager() override func viewDidLoad() { super.viewDidLoad() locationManager.delegate = self; locationManager.requestAlwaysAuthorization() locationManager.desiredAccuracy = kCLLocationAccuracyBest; locationManager.allowsBackgroundLocationUpdates = true locationManager.distanceFilter = kCLDistanceFilterNone Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (timer) in self.locationManager.startUpdatingLocation() } } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { print("didUpdateLocations \(Date())") self.locationManager.stopUpdatingLocation() } }
您需要在AppDelegate类,启动方法,applicationDidEnterBackground和applicationDidBecomeActive方法中进行一些更改。
为位置管理器创建sharedInstance。
仅供参考,请访问http://mobileoop.com/getting-location-updates-for-ios-7-and-8-when-the-app-is-killedterminatedsuspended
它可能对你有帮助。也请查看评论。