2017-01-17 7 views
1

Я отслеживания местоположения пользователя каждый 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() 
} 

Проблема заключается в "didUpdateLocations" больше не запускайте после 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, distanc e: 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.88494
---------- 13:05:49 ---------- точность: 241.075270825073, расстояние: 147.896335551892
---------- 13:06:49 ---------- Точность: 100.101061118372, Расстояние: 16.04822 04840386
---------- 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.6235911449 17

Спасибо заранее-х

+0

Как вы тестируете инициирование значительных обновлений местоположения для startMonitoringSignificantLocationChanges? Может быть, вы просто перестали сильно менять свое местоположение? – Sander

+0

Когда мое приложение убито, я значительно расставил свое приложение, потому что мне нужно местоположение пользователя каждые 1мин в каждом состоянии приложения. –

ответ

1

Я могу представить себе несколько проблем. Но наиболее вероятно, что вы не получаете указанную точность, поскольку

locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation 
locationManager.distanceFilter = kCLDistanceFilterNone 

, как я считаю, не влияют SignificantLocationChanges обновления

От Apple's documentation

После возвращения текущего исправления местоположения, приемник генерирует обновление событий только тогда, когда обнаружено значительное изменение в местоположении пользователя: . Он не полагается на значение в свойстве distanceFilter для генерации событий. Вызов этого метода несколько раз подряд не приводит к автоматическому созданию новых событий. Вызов stopMonitoringSignificantLocationChanges() между ними, однако, вызывает новое начальное событие, которое будет отправлено при следующем вызове этого метода .

Из цитаты, возможно, вы пытаетесь сделать stopMonitoringSignificantLocationChanges и перезапустить его.

Кроме того, обновление местоположения может быть отправлено на ваш метод didUpdateLocations, но не может пройти проверку точности, например, поскольку данная точность ниже и т. Д. И ваш метод таймера не был вызван.


EDIT

// 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() 
} 

Это все, что я изменился.

+0

Можете ли вы рассказать мне, какой код мне нужно изменить в своем посте? –

+0

@ Youssef.Z Я воспроизвел простое приложение и его поведение с небольшими изменениями в коде. И мне удивительно, что непрерывное фоновое обновление даже работает, пока ваше приложение завершено. Я не уверен, сможет ли он пройти Apple Review, потому что это так называемое нарушение правил Apple. Возможно, мне понадобится время, чтобы посмотреть, как это работает со временем, как вы сказали через 20-30 минут. – Sander

+0

Можете ли вы поделиться со мной своим кодом, пожалуйста? –

Смежные вопросы