Swift:在应用程序处于后台时调用.requestLocation()

时间:2019-02-13 18:44:51

标签: ios swift push-notification core-location cllocationmanager

如果我在应用程序的后台调用.requestLocation(),则永远不会调用locationManager didUpateLocations方法。当应用打开时,它可以工作。我设置了.allowsBackgroundLocationUpdates = true,测试电话选择了.authorizedAlways作为授权状态。 requestLocation在后​​台不起作用吗?

为澄清起见,我在didReceiveRemoteNotification委托方法中调用它。每次我向设备发送远程推送通知时,如果应用在后台运行,我都希望调用.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 :(得分:0)

您的问题是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()
    }
}