在后台永远运行Swift 2.0应用程序以更新服务器的位置

我已经编写了下面的代码,它有一个计时器,它每分钟调用一个回调函数。当应用程序进入后台时,我启动了另一个调用相同回调方法的计时器,但后台计时器只工作三分钟。
我知道苹果只允许后台工作三分钟。我的应用程序更像一个跟踪应用程序,它每分钟都跟踪用户的位置,即使应用程序在后台,所以我需要实现这个功能。
我了解到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, target: self, selector: "updateLocation", userInfo: nil, 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, target: self, selector: "updateLocation", userInfo: nil, repeats: true)
        })
    }
}


最佳答案:

在iOS中,定期更新位置有点棘手。有一个很好的线程可以讨论这个问题,您可以阅读更多here
iOS将在几分钟后终止您的应用程序,无论您的计时器是否正在运行。不过,有一种方法可以解决这个问题,我在编写一个离子型应用程序时必须做类似的事情,这样您就可以查看此链接的代码,该链接有一个swift类,用于管理iOS中的定期位置更新。
为了在后台获得周期性的位置,而不是耗尽设备的电池电量,您需要使用位置记录的准确性进行播放,降低位置管理器将其期望的准确度设置为k分配准确度每公里,然后,每隔60秒需要将精度更改为kcallocationaccuracybest,这将使代理能够获得新的、准确的位置更新,然后将精度恢复为低。每次收到更新时都需要初始化计时器。
还有一种方法可以在应用程序被用户杀死后在后台唤醒它,使用应用程序代理让应用程序在被杀死前监听位置的重大变化。当用户的位置发生大跳跃(大约200米)时,这将在后台唤醒应用程序。当应用程序唤醒时,停止对重大更改的监视,并像往常一样重新启动位置服务以继续定期更新。
希望这有帮助。
更新
在Swift 2中,您还需要:

self.locationManager.allowsBackgroundLocationUpdates = true