Стартовые локации обновляются после ввода региона маяка Swift - PullRequest
0 голосов
/ 04 июля 2019

Я делаю приложение для мониторинга региона ibeacon с обновлениями местоположения, когда пользователь входит в этот регион (приложение не на переднем плане). Это обновление местоположения должно быть настроено как точность kCLLocationAccuracyBestForNavigation (потому что я должен сделать отслеживание, пока использование остается в регионе, подписывайтесь на меня существенных изменений не достаточно). Все работает хорошо, но через 20 секунд (иногда 1 минуту или больше) я прекращаю получать обновления местоположений. Я помещаю все ключи в info.plist для постоянного использования местоположения, я включаю фоновые режимы в разделе возможностей и обновления местоположений на фоне.

Я настраиваю locationManager с разными конфигурациями, и всегда SO останавливает обновления моих местоположений. Я использую IOS 12 и Iphone 7 для тестирования.

Способ настройки CLLocationManager:

self.locationManager.desiredAccuracy
=kCLLocationAccuracyBestForNavigation
self.locationManager.activityType = .automotiveNavigation
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.delegate = self
self.locationManager.allowsBackgroundLocationUpdates = true
self.locationManager.pausesLocationUpdatesAutomatically = false

Начать обновление местоположения (когда пользователь входит в регион Ibeacon):

func beaconManager(_ manager: KTKBeaconManager, didEnter region: 
KTKBeaconRegion) {



    self.locationManager.startUpdatingLocation()


}

И, наконец, в местоположениях didUpdate я вызываю веб-сервис:

func locationManager(_ manager: CLLocationManager, 
didUpdateLocations locations: [CLLocation]) {

    //Call web service using alamofire

}

Я прошу вашей помощи, чтобы узнать, правильно ли я выполняю настройки для цели, которую я хочу выполнить, и любую подсказку, которая дает мне знать, почему операционная система убивает мой процесс для получения обновлений местоположений

1 Ответ

2 голосов
/ 04 июля 2019

Получение регулярных обновлений местоположения в фоновом режиме на iOS сложно.Операционная система спроектирована так, чтобы приложения не работали в фоновом режиме, чтобы оптимизировать использование батареи, и она приостанавливает их через некоторое время, если у вас нет нескольких правильных вещей.

Вам нужно сделать три вещи:

  1. Вы должны всегда получать разрешение на местоположение от пользователя (как вы говорите, вы сделали).

  2. Вы должны добавить следующую запись вВаш Info.plist.Это позволит вашему приложению работать бесконечно в фоновом режиме, однако, если вы хотите отправить свое приложение в App Store, эта запись также объявляет рецензентам, что это приложение в фоновом режиме, и вам нужно будет убедить их, что оно предоставляетпользовательское преимущество, основанное на местоположении, и то, что пользователь знает об этом преимуществе.

 <key>UIBackgroundModes</key>
 <array>
     <string>location</string>
 </array>
Вы должны поддерживать фоновый поток, чтобы поддерживать ваше приложение живым.Не имеет значения, действительно ли вы что-то делаете в этом фоновом потоке.Активность этого приложения не позволяет iOS приостановить ваше приложение.
  var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier.invalid

  func extendBackgroundRunningTime() {
    if (backgroundTask != UIBackgroundTaskIdentifier.invalid) {
      // already started
      return
    }
    NSLog("Attempting to extend background running time")

    self.backgroundTask = UIApplication.shared.beginBackgroundTask(withName: "DummyTask", expirationHandler: {
      NSLog("Background task expired by iOS.  Cannot run again until a new beacon region event")
      UIApplication.shared.endBackgroundTask(self.backgroundTask)
      self.backgroundTask = UIBackgroundTaskIdentifier.invalid
    })

    DispatchQueue.global().async {
      while (true) {
        let backgroundTimeRemaining = UIApplication.shared.backgroundTimeRemaining
        // This will be a very large number if you have proper permissions
        // If not, it will generally count down from 10 seconds once you are in the
        // background until iOS suspends your app.
        NSLog("Thread background time remaining: \(backgroundTimeRemaining)")
        Thread.sleep(forTimeInterval: 1.0)
      }
    }
  }
...