LocationManager: иногда startUpdatingLocation не запускается

#ios #swift

#iOS #swift

Вопрос:

Я создал приложение (Swift 4.0), которое, когда оно приближается к iBeacon, запускает локализацию startUpdatingLocation() . Все работает отлично, как с приложением на переднем плане, в фоновом режиме, так и с убитым приложением. Но иногда местоположение не запускается. Похоже, что он никогда не вызывается locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])

Я вошел во все: startUpdatingLocation метод вызывается, и все настроено правильно.

Я пытался также использовать startMonitoringSignificantLocationChanges() в сочетании с startUpdatingLocation() : таким образом, локализация начинается после обратного вызова, который, предположительно, вызывается startMonitoringSignificantLocationChanges (на самом деле первое обнаружение запускается более чем через 500 метров). Но даже этот трюк не всегда работает.

Я также пытался allowDeferredLocationUpdates(untilTraveled distance: CLLocationDistance, timeout: TimeInterval) запустить локализацию, но ничего.

Я также пытался запустить локализацию асинхронно: она не разрешилась.

Я пытался использовать pausesLocationUpdatesAutomatically как true, так и false: ничего.

locationManager(_ manager: CLLocationManager, didFailWithError error: Error) Метод никогда не вызывается.

Ниже locationManager приведен код конфигурации и метод активации локализации:

 func configureLocationService() {
  locationManager = CLLocationManager()

  locationManager?.delegate = AppDelegate.shared
  locationManager?.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
  locationManager?.distanceFilter = Double(Configuration.getMinimumDistanceInMeters())

  locationManager?.activityType = .fitness

  locationManager?.pausesLocationUpdatesAutomatically = true

//  locationManager?.pausesLocationUpdatesAutomatically = false
  locationManager?.allowsBackgroundLocationUpdates = true
  if #available(iOS 11.0, *) {
    locationManager?.showsBackgroundLocationIndicator = true
  } else {
    // Fallback on earlier versions
  }
  locationManager?.requestAlwaysAuthorization()
}

...

func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
  if CLLocationManager.locationServicesEnabled() amp;amp; CLLocationManager.authorizationStatus() == .authorizedAlways {
    manager.startMonitoringSignificantLocationChanges()

    DispatchQueue.main.asyncAfter(deadline: .now()   2, execute: {
      manager.stopMonitoringSignificantLocationChanges()

      DispatchQueue.main.asyncAfter(deadline: .now()   1, execute: {
        manager.startMonitoringSignificantLocationChanges()
        manager.startUpdatingLocation()

        UIApplication.shared.applicationIconBadgeNumber  = 1
        let generator = UINotificationFeedbackGenerator()
        generator.notificationOccurred(.success)
      }
    }
  }
}
  

Я делаю что-то не так? Есть способ ВСЕГДА активировать location с помощью startUpdatingLocation()?

Комментарии:

1. Привет, Матеуш, удалось ли вам решить проблему с тем, что startUpdatingLocation иногда не запускает обновления местоположения в фоновом режиме? У меня тоже такая же проблема, и я не смог найти решение. Очень признателен, если вы могли бы прокомментировать. Спасибо!

Ответ №1:

Если ваш код местоположения уже работает, проблема в другом месте.

Одной из распространенных ситуаций, вызывающих вашу проблему, является настройка вашего диспетчера местоположений в методе жизненного цикла контроллера представления, например viewDidLoad или viewDidAppear . Если приложение запускается в фоновом режиме (с холодного запуска, а не из приостановленного состояния), его контроллер представления никогда не будет отображаться, и методы жизненного цикла представления, такие как viewDidAppear , никогда не будут вызываться.

Для устранения фоновых проблем с местоположением настройте свое приложение на отправку локального уведомления в определенные моменты (методы делегирования приложений, методы жизненного цикла контроллера просмотра, методы делегирования диспетчера местоположений), и вы сможете видеть, что происходит в режиме реального времени.

Комментарии:

1. Я уже использовал метод, аналогичный локальному уведомлению, для отладки (я добавил a UIApplication.shared.applicationIconBadgeNumber = 1 в том AppDelegate , где startUpdatingLocation выполняется): значок увеличивается, но локализация не активируется. Значение locationManager устанавливается appDelegate в методе application (_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool

2. Хорошо, тогда, возможно, вы установили pausesLocationUpdatesAutomatically значение true . Меняет ли значение false значение false?

3. Я попытался pausesLocationUpdatesAutomatically true просто попытаться решить проблему (изначально она была установлена на false )

4. Тогда я бы сказал, попробуйте разместить локальные уведомления в нескольких местах, чтобы отслеживать, что делает приложение. Узнайте, действительно ли вы переходите ко второму Dispatch.main вызову. Я не очень хорошо разбираюсь в GCD, но может ли это вложение привести к тупиковой ситуации?