我试图在后台将位置更新发送到服务器
应用程序有时会在后台崩溃
这是我的位置管理员代表
func locationManager(_ manager: CLLocationManager,didUpdateLocations locations: [CLLocation]) { if let lat = manager.location?.coordinate.latitude,let long = manager.location?.coordinate.longitude { glat = String(lat) glong = String(long) if UIApplication.shared.applicationState == .background { self.updatebackloc(lat,long: long) } if UIApplication.shared.applicationState == .active { self.updateloc(lat,long: long) locationManager.stopUpdatingLocation() let status = CLLocationManager.authorizationStatus() if (status == CLAuthorizationStatus.authorizedAlways) { locationManager.startMonitoringSignificantLocationChanges() } } } }
这是updatebacklog函数
func updatebackloc(_ lat: CLLocationDegrees,long: CLLocationDegrees) { let userID = TegKeychain.get("userID")! let parameters: Parameters = ["userID": userID,"lat": lat,"long":long] Alamofire.request("https://xxxxx.com/ios/updatebackloc.PHP",method: .post,parameters: parameters).validate().responseJSON { response in switch response.result { case .success: if let json = response.result.value { var success = 0 if let dictJSON = json as? [String: AnyObject] { if let successInteger = dictJSON["success"] as? Int { success = successInteger if success == 1 { } } } } case .failure(_): return } } }
didFinishLaunchingWithOptions部分
if let _ = launchOptions?[UIApplicationLaunchOptionsKey.location] { startSignificationLocation() }
在didFinishLaunchingWithOptions上触发startSignificationLocation函数
func startSignificationLocation() { let locationManager = CLLocationManager() locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.requestAlwaysAuthorization() locationManager.allowsBackgroundLocationUpdates = true locationManager.startMonitoringSignificantLocationChanges() }
这是崩溃日志
Crashed: com.apple.main-thread 0 Jemiyet 0x10285b798 specialized AppDelegate.updatebackloc(Double,long : Double) -> () + 4339644312 1 Jemiyet 0x10285b8e4 specialized AppDelegate.locationManager(CLLocationManager,didUpdateLocations : [CLLocation]) -> () (AppDelegate.swift:396) 2 Jemiyet 0x1028540c0 @objc AppDelegate.locationManager(CLLocationManager,didUpdateLocations : [CLLocation]) -> () (AppDelegate.swift) 3 CoreLocation 0x1874f97bc (null) + 77412 4 CoreLocation 0x1874f901c (null) + 75460 5 CoreLocation 0x1874e16b4 (null) + 1004 6 CoreFoundation 0x180ea3590 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 20 7 CoreFoundation 0x180ea2e60 __CFRunLoopDoBlocks + 288 8 CoreFoundation 0x180ea10c8 __CFRunLoopRun + 2436 9 CoreFoundation 0x180dc0c58 CFRunLoopRunSpecific + 436 10 GraphicsServices 0x182c6cf84 GSEventRunModal + 100 11 UIKit 0x18a5195c4 UIApplicationMain + 236 12 Jemiyet 0x1027fe524 main (InBoxInterests.swift:30) 13 libdyld.dylib 0x1808e056c start + 4
这是代码
代码为文本
func locationManager(_ manager: CLLocationManager,didUpdateLocations locations: [CLLocation]) { if let lat = manager.location?.coordinate.latitude,let long = manager.location?.coordinate.longitude { glat = String(lat) glong = String(long) if UIApplication.shared.applicationState == .background { self.updatebackloc(lat,long: long) } if UIApplication.shared.applicationState == .active { self.updateloc(lat,long: long) locationManager.stopUpdatingLocation() let status = CLLocationManager.authorizationStatus() if (status == CLAuthorizationStatus.authorizedAlways) { locationManager.startMonitoringSignificantLocationChanges() } } } } func locationManager(_ manager: CLLocationManager,didFailWithError error: Error) { print(error) } func updateloc(_ lat: CLLocationDegrees,long: CLLocationDegrees) { let userID = TegKeychain.get("userID")! let parameters: Parameters = ["userID": userID,"long":long] Alamofire.request("https://xxxxx.com/ios/updateloc.PHP",parameters: parameters).validate().responseJSON { response in switch response.result { case .success: if let json = response.result.value { var success = 0 if let dictJSON = json as? [String: AnyObject] { if let successInteger = dictJSON["success"] as? Int { success = successInteger if success == 1 { } } } } case .failure(_): return } } } func updatebackloc(_ lat: CLLocationDegrees,long: CLLocationDegrees) { guard let userID = TegKeychain.get("userID") else { return } let parameters: Parameters = ["userID": userID,parameters: parameters).validate().responseJSON { response in switch response.result { case .success: if let json = response.result.value { var success = 0 if let dictJSON = json as? [String: AnyObject] { if let successInteger = dictJSON["success"] as? Int { success = successInteger if success == 1 { } } } } case .failure(_): return } } }
解决方法
您需要将您的后台位置调用包装在UIBackgroundTask中.
var bgTask: UIBackgroundTaskIdentifier? 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. bgTask = application.beginBackgroundTask(withName: "bgLocation",expirationHandler: { if let task = self.bgTask { application.endBackgroundTask(task) self.bgTask = UIBackgroundTaskInvalid } }) }
然后在调用updatebackloc函数时使用正确的后台队列并结束后台任务.
就像是:
func updatebackloc(_ lat: CLLocationDegrees,long: CLLocationDegrees) { let userID = TegKeychain.get("userID")! let parameters: Parameters = ["userID": userID,"long":long] DispatchQueue.global().async { Alamofire.request("https://xxxxx.com/ios/updatebackloc.PHP",parameters: parameters).validate().responseJSON { response in //response handling here... //.... if let appDelegate = UIApplication.shared.delegate as? AppDelegate { if let task = appDelegate.bgTask { UIApplication.shared.endBackgroundTask(task) appDelegate.bgTask = UIBackgroundTaskInvalid } } } } }