ios – 在后台运行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,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

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...