我有一个使用CLLocationManager来请求位置更新的应用。当应用程序收到外部蓝牙设备的通知时,将启动监控。当应用程序位于前台和后台时,应用程序会侦听来自设备的通知,并且在这两种情况下都会成功启动位置更新。
如果在应用程序位于前台时开始监控,我会根据我在位置管理器上配置的距离过滤器获取位置更新。
但是,如果在应用程序处于后台时启动监控,我仍然会获得位置更新,但很少。有没有人知道这是否是预期的行为,或者我是否有可能错误配置了什么?
代码中的设置如下:
fileprivate lazy var locationManager = CLLocationManager()
func initLocationManager(distanceFilter: CLLocationDistance = 270,
desiredAccuracy: CLLocationAccuracy = kCLLocationAccuracyNearestTenMeters,
activityType: CLActivityType = .automotiveNavigation) {
locationManager.requestAlwaysAuthorization()
locationManager.allowsBackgroundLocationUpdates = true
if canGetLocationUpdate() {
locationManager.desiredAccuracy = desiredAccuracy
locationManager.distanceFilter = distanceFilter
locationManager.activityType = activityType
locationManager.delegate = self
}
}
func startLocationMonitoring() {
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
} else {
log.error("Unable to start location monitoring")
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
for location in locations {
log.debug("Got location \(location.coordinate) with speed \(location.speed) and accuracy \(location.horizontalAccuracy)")
}
}
以下是Info.plist:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key><string>To allow the app...</string>
<key>NSLocationAlwaysUsageDescription</key><string>To allow the app...</string>
<key>NSLocationWhenInUseUsageDescription</key><string>To allow the app...</string>
...
<key>UIBackgroundModes</key>
<array>
<string>bluetooth-central</string>
<string>location</string>
</array>
答案 0 :(得分:2)
来自apple docs
如果您的iOS应用程序必须在后台保持监控位置,请使用标准位置服务并指定UIBackgroundModes键的位置值以继续在后台运行并接收位置更新。 (在这种情况下,您还应确保位置管理器的pausesLocationUpdatesAutomatically属性设置为YES以帮助节省电量。)可能需要此类位置更新的应用程序示例是健身或精细导航应用程序。
似乎iOS在后台限制位置更新以节省设备电源。
答案 1 :(得分:0)
您的应用在后台获取的位置更新完全由iOS和您的应用控件完成。
根据Apple关于背景位置服务的文档:
启用此模式不会阻止系统暂停 应用程序,但它确实告诉系统它应该唤醒应用程序 每当有新的位置数据要传递时。因此,这个关键 有效地让应用程序在后台运行以处理位置 无论何时发生都会更新。
有关更多信息,请参阅Background Execution