如何获取用户位置
How to get user location
我每 1 分钟跟踪一次用户位置,这是我的代码:
定位服务:
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()
}
}
应用代理:
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()
}
问题是 "didUpdateLocations" 当我将我的应用程序置于后台 20-30 分钟后不再触发。我错过了什么吗?
数据:
---------- 12:33:41 ---------- accuracy: 100.176340566754, distance: 11.9139937140859
---------- 12:34:41 ---------- accuracy: 100.178246394771, distance: 32.2963845078517
---------- 12:35:42 ---------- accuracy: 100.180248268622, distance: 49.5966777976606
---------- 12:36:42 ---------- accuracy: 100.18076613283, distance: 64.632263503595
---------- 12:37:42 ---------- accuracy: 200.000181126858, distance: 106.803446309979
---------- 12:38:42 ---------- accuracy: 100.390802343119, distance: 18.348623950487
---------- 12:39:43 ---------- accuracy: 150.16852207139, distance: 61.2580288221782
---------- 12:40:43 ---------- accuracy: 241.375319855098, distance: 146.902117049143
---------- 12:41:43 ---------- accuracy: 65.0, distance: 7.48921464439474
---------- 12:42:43 ---------- accuracy: 241.000205573651, distance: 146.987877590092
---------- 12:43:44 ---------- accuracy: 65.0, distance: 7.62405179605234
---------- 12:44:44 ---------- accuracy: 65.0, distance: 7.55896269746399
---------- 12:45:44 ---------- accuracy: 150.000249983526, distance: 38.8944066539055
---------- 12:46:44 ---------- accuracy: 241.139359617865, distance: 147.142388706418
---------- 12:47:45 ---------- accuracy: 65.0, distance: 41.9643473786135
---------- 12:48:45 ---------- accuracy: 241.291934833148, distance: 146.675150610266
---------- 12:49:45 ---------- accuracy: 150.039468172195, distance: 16.6128843089604
---------- 12:50:45 ---------- accuracy: 150.16560931905, distance: 48.6389862868337
---------- 12:51:46 ---------- accuracy: 241.07402885546, distance: 147.229614706109
---------- 12:52:46 ---------- accuracy: 65.0, distance: 7.16417432681208
---------- 12:53:46 ---------- accuracy: 241.06579398531, distance: 146.954120891032
---------- 12:54:46 ---------- accuracy: 241.062179914206, distance: 147.876920566931
---------- 12:55:47 ---------- accuracy: 200.04318538883, distance: 38.136053839707
---------- 12:56:47 ---------- accuracy: 200.180955600876, distance: 88.6844648977498
---------- 12:57:47 ---------- accuracy: 150.202552895379, distance: 91.8166552231255
---------- 12:58:47 ---------- accuracy: 65.0, distance: 57.9455407170564
---------- 12:59:47 ---------- accuracy: 150.166229444757, distance: 34.2036925129397
---------- 13:00:48 ---------- accuracy: 101.846177093094, distance: 0.407274786609172
---------- 13:01:48 ---------- accuracy: 102.125798269775, distance: 48.1922586805367
---------- 13:02:48 ---------- accuracy: 100.180877100619, distance: 16.4299711499485
---------- 13:03:49 ---------- accuracy: 150.094327388532, distance: 77.2190821337144
---------- 13:04:49 ---------- accuracy: 241.079810871571, distance: 146.947321088494
---------- 13:05:49 ---------- accuracy: 241.075270825073, distance: 147.896335551892
---------- 13:06:49 ---------- accuracy: 100.101061118372, distance: 16.0482204840386
---------- 13:07:50 ---------- accuracy: 100.091529189521, distance: 5.74914399862917
---------- 13:08:50 ---------- accuracy: 241.051459353993, distance: 146.942813658832
---------- 13:09:50 ---------- accuracy: 65.8078917547627, distance: 7.06633659121004
---------- 13:10:50 ---------- accuracy: 65.8092481623976, distance: 17.3091393420333
---------- 13:11:51 ---------- accuracy: 244.420168771572, distance: 146.920641901086
---------- 13:12:51 ---------- accuracy: 241.000779705485, distance: 146.871849682004
---------- 13:13:51 ---------- accuracy: 241.000203327672, distance: 144.623591144917
提前致谢
我可以想象几个问题。但最有可能的是你没有得到指定的准确度,因为
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.distanceFilter = kCLDistanceFilterNone
我认为不会影响SignificantLocationChanges
更新
After returning a current location fix, the receiver generates update
events only when a significant change in the user’s location is
detected. It does not rely on the value in the distanceFilter property
to generate events. Calling this method several times in succession
does not automatically result in new events being generated. Calling
stopMonitoringSignificantLocationChanges() in between, however, does
cause a new initial event to be sent the next time you call this
method.
根据引用,也许您尝试 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()
}
这就是我所做的全部更改。
我每 1 分钟跟踪一次用户位置,这是我的代码:
定位服务:
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()
}
}
应用代理:
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()
}
问题是 "didUpdateLocations" 当我将我的应用程序置于后台 20-30 分钟后不再触发。我错过了什么吗?
数据:
---------- 12:33:41 ---------- accuracy: 100.176340566754, distance: 11.9139937140859
---------- 12:34:41 ---------- accuracy: 100.178246394771, distance: 32.2963845078517
---------- 12:35:42 ---------- accuracy: 100.180248268622, distance: 49.5966777976606
---------- 12:36:42 ---------- accuracy: 100.18076613283, distance: 64.632263503595
---------- 12:37:42 ---------- accuracy: 200.000181126858, distance: 106.803446309979
---------- 12:38:42 ---------- accuracy: 100.390802343119, distance: 18.348623950487
---------- 12:39:43 ---------- accuracy: 150.16852207139, distance: 61.2580288221782
---------- 12:40:43 ---------- accuracy: 241.375319855098, distance: 146.902117049143
---------- 12:41:43 ---------- accuracy: 65.0, distance: 7.48921464439474
---------- 12:42:43 ---------- accuracy: 241.000205573651, distance: 146.987877590092
---------- 12:43:44 ---------- accuracy: 65.0, distance: 7.62405179605234
---------- 12:44:44 ---------- accuracy: 65.0, distance: 7.55896269746399
---------- 12:45:44 ---------- accuracy: 150.000249983526, distance: 38.8944066539055
---------- 12:46:44 ---------- accuracy: 241.139359617865, distance: 147.142388706418
---------- 12:47:45 ---------- accuracy: 65.0, distance: 41.9643473786135
---------- 12:48:45 ---------- accuracy: 241.291934833148, distance: 146.675150610266
---------- 12:49:45 ---------- accuracy: 150.039468172195, distance: 16.6128843089604
---------- 12:50:45 ---------- accuracy: 150.16560931905, distance: 48.6389862868337
---------- 12:51:46 ---------- accuracy: 241.07402885546, distance: 147.229614706109
---------- 12:52:46 ---------- accuracy: 65.0, distance: 7.16417432681208
---------- 12:53:46 ---------- accuracy: 241.06579398531, distance: 146.954120891032
---------- 12:54:46 ---------- accuracy: 241.062179914206, distance: 147.876920566931
---------- 12:55:47 ---------- accuracy: 200.04318538883, distance: 38.136053839707
---------- 12:56:47 ---------- accuracy: 200.180955600876, distance: 88.6844648977498
---------- 12:57:47 ---------- accuracy: 150.202552895379, distance: 91.8166552231255
---------- 12:58:47 ---------- accuracy: 65.0, distance: 57.9455407170564
---------- 12:59:47 ---------- accuracy: 150.166229444757, distance: 34.2036925129397
---------- 13:00:48 ---------- accuracy: 101.846177093094, distance: 0.407274786609172
---------- 13:01:48 ---------- accuracy: 102.125798269775, distance: 48.1922586805367
---------- 13:02:48 ---------- accuracy: 100.180877100619, distance: 16.4299711499485
---------- 13:03:49 ---------- accuracy: 150.094327388532, distance: 77.2190821337144
---------- 13:04:49 ---------- accuracy: 241.079810871571, distance: 146.947321088494
---------- 13:05:49 ---------- accuracy: 241.075270825073, distance: 147.896335551892
---------- 13:06:49 ---------- accuracy: 100.101061118372, distance: 16.0482204840386
---------- 13:07:50 ---------- accuracy: 100.091529189521, distance: 5.74914399862917
---------- 13:08:50 ---------- accuracy: 241.051459353993, distance: 146.942813658832
---------- 13:09:50 ---------- accuracy: 65.8078917547627, distance: 7.06633659121004
---------- 13:10:50 ---------- accuracy: 65.8092481623976, distance: 17.3091393420333
---------- 13:11:51 ---------- accuracy: 244.420168771572, distance: 146.920641901086
---------- 13:12:51 ---------- accuracy: 241.000779705485, distance: 146.871849682004
---------- 13:13:51 ---------- accuracy: 241.000203327672, distance: 144.623591144917
提前致谢
我可以想象几个问题。但最有可能的是你没有得到指定的准确度,因为
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.distanceFilter = kCLDistanceFilterNone
我认为不会影响SignificantLocationChanges
更新
After returning a current location fix, the receiver generates update events only when a significant change in the user’s location is detected. It does not rely on the value in the distanceFilter property to generate events. Calling this method several times in succession does not automatically result in new events being generated. Calling stopMonitoringSignificantLocationChanges() in between, however, does cause a new initial event to be sent the next time you call this method.
根据引用,也许您尝试 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()
}
这就是我所做的全部更改。