我有一个应用程序,用户可以通过 GPS 跟踪他的活动。
后台 GPS 更新一切都按预期工作,但在极少数情况下(千分之一),当我的应用程序处于后台时,我只是没有收到来自
CLLocationManager
的更新呼叫。不是立即,而是一段时间后。
我的应用程序开始接收更新,然后突然(可能需要几分钟或几个小时的跟踪)它不会再获得任何位置更新。一旦应用程序再次激活,它就会继续报告位置。但当然那些缺失的位置很糟糕!
我不知道它何时以及为什么会发生,这就是为什么我想问其他人是否已经遇到过同样的问题?我可以说这不是电话或类似的事情打扰了我。我也没有在 didFail 委托方法中得到回调。我只是不再得到任何东西了...... 最大的问题是我不知道如何调试它,因为我无法故意重现它。
非常感谢任何帮助。
编辑:
这是我设置位置管理器的方法
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.distanceFilter = kMinimumDistanceFilter;
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
self.locationManager.pausesLocationUpdatesAutomatically = NO;
self.locationManager.activityType = CLActivityTypeFitness;
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
if ([self.locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)])
{
self.locationManager.allowsBackgroundLocationUpdates = YES;
}
然后当按下开始录音按钮时
[self.locationManager startUpdatingLocation];
编辑2:
如果您启动此服务并且您的应用程序被暂停,系统将停止 事件的传递,直到您的应用程序再次开始运行(在 前景或背景)。如果您的应用程序被终止,则交付 的新地点事件完全停止。因此,如果您的应用程序需要 要在后台接收位置事件,它必须包括 Info.plist 中的 UIBackgroundModes 键(带有位置值) 文件。
我什至不在后台使用
startUpdatingLocation
...但这似乎就是我的应用程序发生的情况。如果应用程序被暂停,我如何才能开始跟踪?那是不可能的,不是吗?因为暂停意味着它没有执行代码?!?
您的
allowsBackgroundLocationUpdates
中是否将 YES
设置为 Info.plist
?
来自文档:
默认情况下,对于与 iOS 9.0 或 稍后,无论最低部署目标如何。
将 UIBackgroundModes 设置为在 Info.plist 中包含“位置”后,您 每当调用时,还必须在运行时将此属性设置为 YES -startUpdatingLocation 意图在后台继续。
当 UIBackgroundModes 不包含时将此属性设置为 YES “位置”是一个致命错误。
将该属性重置为NO相当于省略“location” 来自 UIBackgroundModes 值。访问位置仍然是 只要应用程序正在运行(即未挂起)就允许,并且 具有足够的授权(即它具有 WhenInUse 授权并且是 正在使用,或者具有始终授权)。但是,该应用程序仍将 遵守通常的任务暂停规则。
请参阅 -requestWhenInUseAuthorization 和 -requestAlwaysAuthorization 有关可能的授权值的更多详细信息。
我知道这个问题是 8 年前提出的,但我最近遇到了类似的问题,想与社区分享我的发现。
问题似乎可能与应用程序进入后台后设置 allowedBackgroundLocationUpdates 太晚有关。就我而言,我测试了以下代码:
NotificationCenter.default.publisher(for: UIApplication.didEnterBackgroundNotification)
.sink { [weak self] _ in
guard let self = self else { return }
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.locationManager.allowsBackgroundLocationUpdates = true
print("allowsBackgroundLocationUpdates = true")
}
}
.store(in: &cancellables)
尽管将 allowedBackgroundLocationUpdates 设置为 true,但位置更新在后台失败,在 didFailWithError 回调中触发此错误:
The operation couldn’t be completed. (kCLErrorDomain error 1.)
看来必须在应用程序进入后台之前立即设置allowsBackgroundLocationUpdates才能可靠地工作。我希望这可以帮助其他面临类似问题的人。