我每隔1分钟跟踪用户位置,这是我的代码:
LocationService:
import CoreLocation
import CoreData
class LocationService: NSObject, CLLocationManagerDelegate {
static let shared = LocationService()
var locationManager: CLLocationManager!
var currentLocation: CLLocation!
var timer = Timer()
var bgTask = UIBackgroundTaskInvalid
func startUpdatingLocation() {
locationManager = CLLocationManager()
locationManager?.requestAlwaysAuthorization()
locationManager?.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager?.distanceFilter = kCLDistanceFilterNone
if #available(iOS 9.0, *) {
locationManager?.allowsBackgroundLocationUpdates = true
}
locationManager?.pausesLocationUpdatesAutomatically = false
locationManager?.delegate = self
locationManager?.startUpdatingLocation()
}
func stopUpdatingLocation() {
locationManager?.stopUpdatingLocation()
timer.invalidate()
}
func startMonitoringLocation() {
stopUpdatingLocation()
locationManager?.startMonitoringSignificantLocationChanges()
}
func changeLocationAccuracy() {
switch locationManager.desiredAccuracy {
case kCLLocationAccuracyBestForNavigation:
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
locationManager.distanceFilter = 99999
case kCLLocationAccuracyThreeKilometers:
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.distanceFilter = kCLDistanceFilterNone
default: break
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
bgTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
UIApplication.shared.endBackgroundTask(self.bgTask)
self.bgTask = UIBackgroundTaskInvalid
})
guard let newLocation = locations.last else {
return
}
let interval = newLocation.timestamp.timeIntervalSinceNow
if abs(interval) > 5 || locationManager.desiredAccuracy != kCLLocationAccuracyBestForNavigation {
return
}
if newLocation.horizontalAccuracy < 0 {
return
}
if currentLocation == nil && newLocation.horizontalAccuracy > 70 {
return
}
currentLocation = newLocation
timer = Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(LocationService.changeLocationAccuracy), userInfo: nil, repeats: false)
changeLocationAccuracy()
}
}
AppDelegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if launchOptions?[UIApplicationLaunchOptionsKey.location] != nil {
LocationService.shared.startUpdatingLocation()
}
return true
}
func applicationWillTerminate(_ application: UIApplication) {
LocationService.shared.startMonitoringLocation()
}
问题是&#34; didUpdateLocations&#34;当我将我的应用程序置于后台时,20-30分钟后不再触发。我错过了什么吗?
数据:
---------- 12:33:41 ----------准确度:100.176340566754,距离:11.9139937140859
---------- 12:34:41 ----------准确度:100.178246394771,距离:32.2963845078517
---------- 12:35:42 ----------准确度:100.180248268622,距离:49.5966777976606
---------- 12:36:42 ----------精度:100.18076613283,距离:64.632263503595
---------- 12:37:42 ----------精度:200.000181126858,距离:106.803446309979
---------- 12:38:42 ----------准确度:100.390802343119,距离:18.348623950487
---------- 12:39:43 ----------准确度:150.16852207139,距离:61.2580288221782
---------- 12:40:43 ----------准确度:241.375319855098,距离:146.902117049143
---------- 12:41:43 ----------准确度:65.0,距离:7.48921464439474
---------- 12:42:43 ----------准确度:241.000205573651,距离:146.987877590092
---------- 12:43:44 ----------准确度:65.0,距离:7.62405179605234
---------- 12:44:44 ----------准确度:65.0,距离:7.55896269746399
---------- 12:45:44 ----------准确度:150.000249983526,距离:38.8944066539055
---------- 12:46:44 ----------精度:241.139359617865,距离:147.142388706418
---------- 12:47:45 ----------准确度:65.0,距离:41.9643473786135
---------- 12:48:45 ----------准确度:241.291934833148,距离:146.675150610266
---------- 12:49:45 ----------准确度:150.039468172195,距离:16.6128843089604
---------- 12:50:45 ----------准确度:150.16560931905,距离:48.6389862868337
---------- 12:51:46 ----------准确度:241.07402885546,距离:147.229614706109
---------- 12:52:46 ----------准确度:65.0,距离:7.16417432681208
---------- 12:53:46 ----------精度:241.06579398531,距离:146.954120891032
---------- 12:54:46 ----------精度:241.062179914206,距离:147.876920566931
---------- 12:55:47 ----------精度:200.04318538883,距离:38.136053839707
---------- 12:56:47 ----------准确度:200.180955600876,距离:88.6844648977498
---------- 12:57:47 ----------准确度:150.202552895379,距离:91.8166552231255
---------- 12:58:47 ----------准确度:65.0,距离:57.9455407170564
---------- 12:59:47 ----------准确度:150.166229444757,距离:34.2036925129397
---------- 13:00:48 ----------准确度:101.846177093094,距离:0.407274786609172
---------- 13:01:48 ----------准确度:102.125798269775,距离:48.1922586805367
---------- 13:02:48 ----------精度:100.180877100619,距离:16.4299711499485
---------- 13:03:49 ----------准确度:150.094327388532,距离:77.2190821337144
---------- 13:04:49 ----------准确度:241.079810871571,距离:146.947321088494
---------- 13:05:49 ----------精度:241.075270825073,距离:147.896335551892
---------- 13:06:49 ----------准确度:100.101061118372,距离:16.0482204840386
---------- 13:07:50 ----------准确度:100.091529189521,距离:5.74914399862917
---------- 13:08:50 ----------精度:241.051459353993,距离:146.942813658832
---------- 13:09:50 ----------准确度:65.8078917547627,距离:7.06633659121004
---------- 13:10:50 ----------准确度:65.8092481623976,距离:17.3091393420333
---------- 13:11:51 ----------准确度:244.420168771572,距离:146.920641901086
---------- 13:12:51 ----------准确度:241.000779705485,距离:146.871849682004
---------- 13:13:51 ----------准确度:241.000203327672,距离:144.623591144917
提前感谢
答案 0 :(得分:1)
我可以想象几个问题。但最有可能的是,你没有获得指定的准确性,因为
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.distanceFilter = kCLDistanceFilterNone
因为我认为不会影响SignificantLocationChanges
更新
返回当前位置修复后,接收器会生成更新 仅当用户位置发生重大变化时才会发生事件 检测。它不依赖于distanceFilter属性中的值 生成事件。连续多次调用此方法 不会自动导致生成新事件。调用 但是,stopMonitoringSignificantLocationChanges()之间的确如此 导致下次调用时发送新的初始事件 方法
从引用中,您可能尝试stopMonitoringSignificantLocationChanges
并重新启动它。
此外,位置更新可能会发送到您的didUpdateLocations
方法,但无法通过您的准确性检查,例如因为给定的准确度较低等等。并且您的计时器方法未被调用结果。
修改强>
// to start location update properly and register for notifications
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
LocationService.shared.startUpdatingLocation()
let settings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
return true
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//.....
// added local notification to look at the update
let notification = UILocalNotification()
notification.alertBody = "Location: \(currentLocation), task: \(bgTask)"
notification.fireDate = Date().addingTimeInterval(1.0)
notification.soundName = UILocalNotificationDefaultSoundName
UIApplication.shared.scheduleLocalNotification(notification)
timer = Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(LocationService.changeLocationAccuracy), userInfo: nil, repeats: false)
changeLocationAccuracy()
}
这就是我所改变的一切。