[英]How do I track in the background in iOS a user walking and calculate the distance traveled so far using Swift and Xcode?
How do I track in the background in iOS a user walking in Apple MapKit or Google Maps Platform for iOS and calculate the distance traveled so far using Swift and Xcode?我如何在 iOS 的后台跟踪用户在 Apple MapKit 或 Google Maps Platform for iOS 中行走并使用 Swift 和 Xcode 计算到目前为止行进的距离?
I have tried using MapKit.我试过使用 MapKit。 The problem I get is that when the iOS device is locked, Core Location stops tracking the device.
我遇到的问题是,当 iOS 设备被锁定时,核心位置停止跟踪设备。 When the device is unlocked and the app comes to the foreground, Core Location starts tracking again and draws a straight line from the last point tracked to the point tracked when the app comes to the foreground, thus skipping all the time that the device is locked.
当设备解锁,应用程序进入前台时,Core Location 再次开始跟踪,从最后一个跟踪点到应用程序进入前台时跟踪的点绘制一条直线,从而跳过设备锁定的所有时间. If Google Maps Platform works better for this purpose, I am willing to use it.
如果谷歌地图平台在这方面效果更好,我愿意使用它。
Following is the relevant code:以下是相关代码:
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.allowsBackgroundLocationUpdates = true
if #available(iOS 11.0, *) {
locationManager.showsBackgroundLocationIndicator = true
}
let status = CLLocationManager.authorizationStatus()
if status == .authorizedAlways || status == .authorizedWhenInUse || status == .restricted {
locationManager.startUpdatingLocation()
locationManager.startMonitoringSignificantLocationChanges()
} else {
locationManager.requestAlwaysAuthorization()
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedAlways || status == .authorizedWhenInUse || status == .restricted {
locationManager.startUpdatingLocation()
locationManager.startMonitoringSignificantLocationChanges()
} else {
locationManager.requestAlwaysAuthorization()
}
}
Did you add in your .plist, Privacy - Location Always and When In Use Usage Description
and Privacy - Location When In Use Usage Description
?您是否在 .plist 中添加了
Privacy - Location Always and When In Use Usage Description
和Privacy - Location When In Use Usage Description
?
Then as you are probably conforming CLLocationManagerDelegate
in the method didUpdateLocations
you should be able to perform your code.然后,由于您可能在
didUpdateLocations
方法中符合CLLocationManagerDelegate
,您应该能够执行您的代码。
My mistake was that I was creating the line with the user location from the map instead of the user location passed to the didUpdateLocations method.我的错误是我使用地图中的用户位置而不是传递给 didUpdateLocations 方法的用户位置创建了线条。 The userLocation property on the map does not update in the background, whereas the userLocation property of CLLocationManager does update in the background.
地图上的 userLocation 属性不会在后台更新,而 CLLocationManager 的 userLocation 属性会在后台更新。
Here is the corrected code, with a comment on the line that I corrected:这是更正后的代码,在我更正的行上有注释:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("didUpdateLocations", locations)
if let userLocation = locations.first, polyline != nil {
let userLocationMapPoint = MKMapPoint(userLocation.coordinate)
let lastUserLocationMapPoint = MKMapPoint(route.last!)
totalDistance += userLocationMapPoint.distance(to: lastUserLocationMapPoint)
mapView.removeOverlay(polyline)
route.append(userLocation.coordinate) // changed from route.append(mapView.userLocation.coordinate)
polyline = MKPolyline(coordinates: route, count: route.count)
mapView.addOverlay(polyline)
}
print("latitude:", mapView.userLocation.coordinate.latitude, "longitude:", mapView.userLocation.coordinate.longitude)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.