Swift: вызов .requestLocation (), когда приложение находится в фоновом режиме - PullRequest
0 голосов
/ 13 февраля 2019

Если я вызываю .requestLocation() в фоновом режиме моего приложения, метод locationManager didUpateLocations никогда не вызывается.Работает, когда приложение открыто.Я установил .allowsBackgroundLocationUpdates = true и тестовый телефон выбрал .authorizedAlways для статуса авторизации.requestLocation не работает в фоновом режиме?

Чтобы уточнить, я вызываю его в методе делегата didReceiveRemoteNotification.Каждый раз, когда я отправляю удаленное push-уведомление на устройство, я хочу, чтобы .requestLocation() вызывалось, если приложение работает в фоновом режиме.Разве это невозможно?

didReceiveRemoteNotification:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

    if CLLocationManager.authorizationStatus() == .authorizedAlways {
        locationManager.requestLocation()
    }

    completionHandler(UIBackgroundFetchResult.newData)
}

1 Ответ

0 голосов
/ 14 февраля 2019

Ваша проблема в том, что requestLocation завершится асинхронно;определение местоположения пользователя и вызов метода делегата didUpdateLocations может занять некоторое время.

Вызов completionHandler сообщает iOS о завершении фоновой обработки.Поскольку вы делаете это сразу после requestLocation iOS приостанавливает ваше приложение до вызова делегата местоположения.

Вы можете использовать DispatchGroup, чтобы определить, когда местоположение было получено, и вы готовы к приостановке:

class AppDelegate: UIApplicationDelegate, CLLocationManagerDelegate {
    var backgroundDispatchGroup: DispatchGroup?


    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

        if CLLocationManager.authorizationStatus() == .authorizedAlways {

            self.backgroundDispatchGroup = DispatchGroup()
            self.backgroundDispatchGroup?.enter()
            locationManager.requestLocation()

            self.backgroundDispatchGroup?.notify {
                completionHandler(UIBackgroundFetchResult.newData)
                self.backgroundDispatchGroup = nil
            }

         } else {
             completionHandler(UIBackgroundFetchResult.noData)
         }
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        // Do whatever with the location

        self.backgroundDispatchGroup?.leave()
    }
}
...