ios - 持续位置更新后台iOS13
问题描述
我目前正在 iOS 13 中测试后台定位模式,因为我想在后台跟踪用户的位置和运动(使用 CMMotionManager)。因此,我有自己的(单例)类来处理位置跟踪。我通过以下方式初始化 CLLocationManager:
func initializeLocationManager() -> CLLocationManager {
let manager = locationManager ?? CLLocationManager()
manager.delegate = self
manager.requestAlwaysAuthorization()
manager.allowsBackgroundLocationUpdates = true
manager.pausesLocationUpdatesAutomatically = false
manager.distanceFilter = kCLDistanceFilterNone
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.activityType = .other
return manager
}
然后我启动以下服务:
func startLocationServices() {
// ...
locationManager.startUpdatingLocation()
locationManager.startMonitoringVisits()
locationManager.startMonitoringSignificantLocationChanges()
// ...
}
另外,我实现了CLLocationManagerDelegate-methods didChangeAuthorization()、didUpdateLocation()。
在 info.plist 文件中,我附加了以下条目:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>...</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>...</string>
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
在我的 ViewController 中,我调用 startLocationServices。目前,我将应用程序跟踪位置数据的授权设置为“.authorizedAlways”
位置更新在大约 60 - 130 分钟后停止。
为了解决这个问题,我已经添加了 didFinishLaunchingWithOptions 函数,它会再次触发位置更新:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if let launchOptions = launchOptions,
let isLocationKey = launchOptions[UIApplication.LaunchOptionsKey.location] as? Bool,
isLocationKey {
restartServices()
}
return true
}
当应用程序使用此功能被唤醒时,我设法获得了一些测试的连续数据,但有时应用程序会在几分钟后再次挂起。
最后,我还尝试了一个计时器,它每 5 分钟重新启动一次位置跟踪,但这似乎根本不会影响更新持续时间。
所以我的问题是,是否有办法在后台连续接收位置更新,或者我是否缺少一些选项?
提前致谢。
编辑:我在 iOS 12 上测试了该应用程序,并在 5/5 测试中不断更新。所以我猜这个问题与iOS 13有关。
解决方案
代码没有错!!,我遇到了同样的问题,经过研究我发现
在 WWDC19 主题演讲中,Apple 宣布对 iOS 13 中位置权限的工作方式进行了两项更改。第一项更改使用户可以选择仅与您的应用程序共享他们的位置一次。这样可以更轻松地尝试位置功能,并帮助用户将敏感的位置数据保密。
第一个值得注意的变化是,即使您调用requestAlwaysAuthorization
,用户也只会在权限对话框中获得“刚刚”和“使用时”选项。如果用户授予您“使用时”权限,并且您尝试在后台扫描位置,则只有这样,用户才会看到一个对话框以授予后台权限。
因此,当用户授予WhenInUseUsage 权限时,您将进入always
并且CLAuthorizationStatus
如果用户选择Allow Once
CLAuthorizationStatus
将被休息到notDetermined
一旦应用程序再次启动
您可以查看这篇文章以获取详细信息 https://medium.com/q42-engineering/apple-location-permission-ios13-1e0e59002889
这是视频https://developer.apple.com/videos/play/wwdc2019/705/
编辑
After When In User 用户授予用户权限后,iOS 将在几天后向用户显示另一个对话框,以将权限从使用时更改为始终允许。
所以现在没有办法像我们以前那样直接要求用户总是立即允许权限。
推荐阅读
- javascript - Tabulator.js 表格元素检索行的索引并用作其他绘图的控制元素
- c# - asp.net C# gridview 分页禁用其他按钮
- git - 我可以在不更改本地存储库内容的情况下从目标分支切换到本地 master 吗?
- ide - 在 html 元素中搜索和替换文本
- dbt - 如何使用日志错误 FileNotFound 运行 dbt 以触发不为 0 的退出代码?
- sql-server - 根据记录之间的分钟数在 SQL 中递归地分组记录
- youtube - 嵌入包含所有数据的 youtube 视频,如 youtube 网站
- r - 相对于每个点,按时间和位置窗口重复有效地过滤大型数据集
- javascript - Javascript Keydown 事件处理程序无法正常工作
- c# - NReco 为每一帧设置不同的持续时间