在后台启动ViewController中获取用户位置

时间:2018-11-07 15:28:13

标签: ios swift background cllocationmanager lifecycle

即使应用处于后台状态或未运行,我的应用也需要收集用户位置,因此我已将 CLLocationManager 实施为startMonitoringSignificantLocationChanges AppDelegate 中这个:

class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {

    var window: UIWindow?
    var locationMgrSLC = CLLocationManager()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        window?.tintColor = kMainRedColor

        //Other setups ...

        //Init Location for Significant Location Changes
        locationMgrSLC.desiredAccuracy = kCLLocationAccuracyBest
        locationMgrSLC.distanceFilter = kCLDistanceFilterNone
        locationMgrSLC.allowsBackgroundLocationUpdates = true
        locationMgrSLC.delegate = self
        if launchOptions?[UIApplication.LaunchOptionsKey.location] != nil { //launch service again if is background
            startMonitoringSignificantLocationChanges()
        }

        return true
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits

        startMonitoringSignificantLocationChanges()
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

        locationMgrSLC.stopMonitoringSignificantLocationChanges()
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.

        startMonitoringSignificantLocationChanges()
    }

    // MARK: Background location update

    func startMonitoringSignificantLocationChanges() {
        if CLLocationManager.locationServicesEnabled() && CLLocationManager.authorizationStatus() == .authorizedAlways {

            locationMgrSLC.startMonitoringSignificantLocationChanges()

            if CLLocationManager.significantLocationChangeMonitoringAvailable() {
                print("[Background location] started...")
            }
            else {
                print("[Background location] SLC not available...")
            }
        }
        else {
            print("[Background location] cannot start (not authorized)")
        }
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
        if let userLocation = locations.last {

            //Send data to server ...

        }
        else {
            print("[Background location] no user location found")
        }
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("[Background location] didFailWithError: \(error.localizedDescription)")
    }
}

此实现按预期运行,但是看起来像这样,当iOS用新位置唤醒应用程序(从非活动状态到后台)时,整个应用程序都在后台启动,就像它是由用户启动的一样。我知道这是因为一些API请求是从主ViewController发出的。

这是正常行为吗?如何防止主视图控制器在后台启动?

0 个答案:

没有答案