即使应用处于后台状态或未运行,我的应用也需要收集用户位置,因此我已将 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发出的。
这是正常行为吗?如何防止主视图控制器在后台启动?