如何获取用户位置

时间:2017-01-17 19:03:04

标签: ios swift3 xcode8 cllocationmanager

我每隔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

提前感谢

1 个答案:

答案 0 :(得分:1)

我可以想象几个问题。但最有可能的是,你没有获得指定的准确性,因为

locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.distanceFilter = kCLDistanceFilterNone

因为我认为不会影响SignificantLocationChanges更新

来自Apple's documentation

  

返回当前位置修复后,接收器会生成更新   仅当用户位置发生重大变化时才会发生事件   检测。它不依赖于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()
}

这就是我所改变的一切。