在Swift 2.0中每隔n分钟更新一次背景中的位置

时间:2015-10-16 14:50:46

标签: background swift2

使用AppDelegate.swift中的代码,我可以每30秒获得一次位置更新。但是,在180秒后,backgroundTimeRemaining将执行后台执行。
plist在UIBackgroundModes中有“location”标签 我有两个问题:

  1. 为什么backgroundTimeRemaining没有重置?
  2. 如果我执行startUpdatingLocation()然后stopUpdatingLocation()以节省电量,那么我将无法再次更新位置。
  3. import UIKit
    import CoreLocation
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {
    
        var window: UIWindow?
        let locationManager = CLLocationManager()
        var pos = 0
        var LatitudeGPS = NSString()
        var LongitudeGPS = NSString()
        var speedGPS = NSString()
        var Course = NSString()
        var Altitude = NSString()
        var bgtimer = NSTimer()
    
        func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
            // Override point for customization after application launch.
            return true
        }
    
        var backgroundUpdateTask: UIBackgroundTaskIdentifier!
    
        func beginBackgroundUpdateTask() {
            self.backgroundUpdateTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({
            self.endBackgroundUpdateTask()
            })
        }
    
        func endBackgroundUpdateTask() {
            UIApplication.sharedApplication().endBackgroundTask(self.backgroundUpdateTask)
            self.backgroundUpdateTask = UIBackgroundTaskInvalid
        }
    
        func doBackgroundTask() {
    
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
                self.beginBackgroundUpdateTask()
    
                // Do something
                self.StartupdateLocation()
    
                self.bgtimer = NSTimer.scheduledTimerWithTimeInterval(30, target: self, selector: "bgtimer:", userInfo: nil, repeats: true)
                NSRunLoop.currentRunLoop().addTimer(self.bgtimer, forMode: NSDefaultRunLoopMode)
                NSRunLoop.currentRunLoop().run()
    
                // End the background task.
                self.endBackgroundUpdateTask()
            })
        }
    
        func bgtimer(timer:NSTimer!){
    
            print("Fired from Background ************************************")
    
            updateLocation()
    
            print("Position Report: \(pos)")
        }
    
        func applicationDidEnterBackground(application: UIApplication) {
    
            self.doBackgroundTask()
        }
    
        func StartupdateLocation() {
            locationManager.delegate = self
            locationManager.startUpdatingLocation()
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
            locationManager.distanceFilter = kCLDistanceFilterNone
            locationManager.requestWhenInUseAuthorization()
            locationManager.allowsBackgroundLocationUpdates = true
            locationManager.pausesLocationUpdatesAutomatically = false
        }
    
        func updateLocation() {
            pos++
    
            //locationManager.startUpdatingLocation()
            //locationManager.stopUpdatingLocation()
    
            print("Latitude: \(LatitudeGPS)")
            print("Longitude: \(LongitudeGPS)")
            print("Speed: \(speedGPS)")
            print("Heading: \(Course)")
            print("Altitude BG: \(Altitude)")
            print(UIApplication.sharedApplication().backgroundTimeRemaining)
        }
    
        func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    
            LatitudeGPS = String(format: "%.10f", manager.location!.coordinate.latitude)
            LongitudeGPS = String(format: "%.10f", manager.location!.coordinate.longitude)
            speedGPS = String(format: "%.3f", manager.location!.speed)
            Altitude = String(format: "%.3f", manager.location!.altitude)
            Course = String(format: "%.3f", manager.location!.course)
        }
    }
    

    编辑*** 我在ViewController中初始化updateLocation后解决了这个问题。

1 个答案:

答案 0 :(得分:0)

import UIKit
import CoreLocation
@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate,CLLocationManagerDelegate {
var window: UIWindow?
var locationManager = CLLocationManager()
var backgroundUpdateTask: UIBackgroundTaskIdentifier!
var bgtimer = Timer()
var latitude: Double = 0.0
var longitude: Double = 0.0
var current_time = NSDate().timeIntervalSince1970
var timer = Timer()
var f = 0
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    self.doBackgroundTask()
    return true
}


func applicationWillResignActive(_ application: UIApplication) {
}

func applicationWillEnterForeground(_ application: UIApplication) {
    print("Entering foreBackground")
}

func applicationDidBecomeActive(_ application: UIApplication) {
}

func applicationWillTerminate(_ application: UIApplication) {
}

func applicationDidEnterBackground(_ application: UIApplication) {
    print("Entering Background")
   // self.doBackgroundTask()
}

func doBackgroundTask() {

    DispatchQueue.main.async {

        self.beginBackgroundUpdateTask()

        self.StartupdateLocation()


        self.bgtimer = Timer.scheduledTimer(timeInterval:-1, target: self, selector: #selector(AppDelegate.bgtimer(_:)), userInfo: nil, repeats: true)
        RunLoop.current.add(self.bgtimer, forMode: RunLoopMode.defaultRunLoopMode)
        RunLoop.current.run()

        self.endBackgroundUpdateTask()

    }
}

func beginBackgroundUpdateTask() {
    self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
        self.endBackgroundUpdateTask()
    })
}

func endBackgroundUpdateTask() {
    UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
    self.backgroundUpdateTask = UIBackgroundTaskInvalid
}

func StartupdateLocation() {
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.distanceFilter = kCLDistanceFilterNone
    locationManager.requestAlwaysAuthorization()
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.pausesLocationUpdatesAutomatically = false
    locationManager.startUpdatingLocation()
}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    print("Error while requesting new coordinates")
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    let locValue:CLLocationCoordinate2D = manager.location!.coordinate

    self.latitude = locValue.latitude
    self.longitude = locValue.longitude
    f+=1
    print("New Coordinates: \(f) ")
    print(self.latitude)
    print(self.longitude)
}

@objc func bgtimer(_ timer:Timer!){
    sleep(2)
  /*  if UIApplication.shared.applicationState == .active {
         timer.invalidate()
    }*/
    self.updateLocation()
}

func updateLocation() {
    self.locationManager.startUpdatingLocation()
    self.locationManager.stopUpdatingLocation()
}}

我添加了睡眠功能以延迟调用该位置并将信息发送到服务器

由于此操作正在运行,因此应用程序处于活动状态并转到后台。如果只需要后台进程,请从didFinishLaunchingWithOptions中删除或注释函数self.doBackgroundTask(),并在applicationdidEnterBackground中删除self.doBackgroundTask()的注释。然后删除函数bgtimer()中的注释,因为一旦应用程序进入活动状态,后台进程就必须停止。

感谢您使用您的代码我能够做出一些  连续运行的替代解决方案。