我写了下面的代码,它有一个每分钟调用回调函数的计时器.当应用程序进入后台时,我启动了另一个调用同一回调方法的计时器,但后台计时器只工作了三分钟.
我明白苹果只允许后台任务只有三分钟.我的应用程序更像是跟踪应用程序,即使应用程序在后台也可以跟踪用户的位置,因此我需要实现此功能.
我了解到,要使用beginBackgroundTaskWithExpirationHandler,但是我不知道我的实现是否正确.
注意:在plist toApp寄存器中有必要的后台模式用于位置更新.
override func viewDidLoad() { super.viewDidLoad() timeInMinutes = 1 * 60 self.locationManager.requestAlwaysAuthorization() self.locationManager.requestWhenInUseAuthorization() if CLLocationManager.locationServicesEnabled() { locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters locationManager.startUpdatingLocation() } var timer = NSTimer.scheduledTimerWithTimeInterval( timeInMinutes,target: self,selector: "updateLocation",userInfo: nil,repeats: true) } func locationManager(manager: CLLocationManager,didUpdateLocations locations: [CLLocation]){ let locValue:CLLocationCoordinate2D = manager.location!.coordinate self.latitude = locValue.latitude self.longitude = locValue.longitude if UIApplication.sharedApplication().applicationState == .Active { } else { backgroundTaskIdentifier = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({ () -> Void in self.backgroundTimer.invalidate() self.backgroundTimer = NSTimer.scheduledTimerWithTimeInterval( 60.0,repeats: true) }) } } func updateLocation() { txtlocationLabel.text = String(n) self.n = self.n+1 var timeRemaining = UIApplication.sharedApplication().backgroundTimeRemaining print(timeRemaining) if timeRemaining > 60.0 { self.GeoLogLocation(self.latitude,Longitude: self.longitude) { results in print("View Controller: \(results)") self.CheckResult(String(results)) } } else { if timeRemaining == 0 { UIApplication.sharedApplication().endBackgroundTask(backgroundTaskIdentifier) } backgroundTaskIdentifier2 = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({ () -> Void in self.backgroundTimer.invalidate() self.backgroundTimer = NSTimer.scheduledTimerWithTimeInterval( 60.0,repeats: true) }) } }
解决方法
定期更新在IOS中有点棘手.有一个很好的线程讨论这个,你可以阅读更多
here
几分钟后,iOS会终止你的应用程序,无论你的计时器是否运行.有一个方法,虽然,我必须做一些类似的事情,当编写一个离子应用程序,所以你可以检查这个here的代码,该链接有一个快速的类来管理iO中的定期位置更新.
为了在后台获取周期性的位置,不会耗尽设备的电池,您需要播放位置记录的准确性,降低位置管理器将其所需的精度设置为kCLLocationAccuracyThreeKilometer的准确性,然后每60秒需要将精度更改为kCLLocationAccuracyBest,这将使代理能够获得新的,准确的位置更新,然后将精度恢复到低.每次接收到更新时,需要初始化定时器.
还有一种在用户被杀死后在后台唤醒应用程序的方法,使用应用程序委托让应用程序在杀死之前监听位置的重大更改.当用户的位置发生大跳跃(大约200ms)时,这将在后台唤醒应用程序.当应用程序唤醒时,停止监视重大更改,并照常重新启动位置服务,以继续定期更新.
希望这可以帮助.
更新
在Swift 2中,您还需要:
self.locationManager.allowsBackgroundLocationUpdates = true