ios - 当应用程序处于后台或被杀死时如何定期获取新位置

标签 ios swift3 xcode8 cllocation

当我的应用程序处于后台或被杀死时,我想每 1 分钟获取一次新位置。 这是我的代码:

定位服务:

class LocationService: NSObject, CLLocationManagerDelegate {

    static let shared = LocationService()
    var locationManager = CLLocationManager()
    var significatLocationManager = CLLocationManager()
    var currentLocation: CLLocation!
    var timer = Timer()
    var bgTask = UIBackgroundTaskInvalid

    func startUpdatingLocation() {
        locationManager.requestAlwaysAuthorization()
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.distanceFilter = kCLDistanceFilterNone
        if #available(iOS 9.0, *) {
            locationManager.allowsBackgroundLocationUpdates = true
        }
        locationManager.delegate = self
        locationManager.startUpdatingLocation()
    }

    func stopUpdatingLocation() {
        locationManager.stopUpdatingLocation()
        timer.invalidate()
    }

    func restartUpdatingLocation() {
        locationManager.stopMonitoringSignificantLocationChanges()
        timer.invalidate()
        startUpdatingLocation()
    }

    func startMonitoringLocation() {
        locationManager.stopUpdatingLocation()
        locationManager.startMonitoringSignificantLocationChanges()
        timer.invalidate()
    }

    func changeLocationAccuracy(){
        switch locationManager.desiredAccuracy {
        case kCLLocationAccuracyBest:
            locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
            locationManager.distanceFilter = 99999
        case kCLLocationAccuracyThreeKilometers:
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
            locationManager.distanceFilter = kCLDistanceFilterNone
        default: break
        }
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        bgTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
            UIApplication.shared.endBackgroundTask(self.bgTask)
            self.bgTask = UIBackgroundTaskInvalid
        })

        currentLocation = locations.last!

        let interval = currentLocation.timestamp.timeIntervalSinceNow
        let accuracy = self.locationManager.desiredAccuracy

        if abs(interval) < 60 && accuracy != kCLLocationAccuracyThreeKilometers {        
            timer = Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(LocationService.changeLocationAccuracy), userInfo: nil, repeats: false)
            changeLocationAccuracy()
        }
    } 
}

应用委托(delegate):

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
     if launchOptions?[UIApplicationLaunchOptionsKey.location] != nil {
          LocationService.shared.restartUpdatingLocation()
     }
}

func applicationDidEnterBackground(_ application: UIApplication) {
     LocationService.shared.restartUpdatingLocation()
}

func applicationWillTerminate(_ application: UIApplication) {
     LocationService.shared.startMonitoringLocation()
}

View Controller :

override func viewDidLoad() {
    LocationService.shared.startUpdatingLocation()
}

但是我的代码不工作,当我的应用程序在后台运行几分钟后,我没有得到新的位置。当我的应用程序被暂停或终止时也是如此。 有什么解决办法吗?请注意我使用的是 Swift 3 和 xcode 8.1。

提前致谢

最佳答案

  • 如果您在应用程序已在后台时调用 startUpdatingLocation,那么您只会在几分钟内收到位置更新。

  • 如果您在应用程序处于前台时调用 startUpdatingLocation,然后您的应用程序移至后台,您将继续无限期地接收位置更新。

  • 如果您在前台调用 startMonitoringSignificantLocationChanges 并保持启用状态,那么您可以在后台调用 startUpdatingLocation 并无限期地接收更新.

  • 如果用户终止您的应用(通过在应用切换器中向上滑动),那么您将不会再收到位置更新,直到用户重新启动您的应用。

由于您的代码在移动到仅获取位置更新的后台时会停止并启动位置监控几分钟。如果您在前台启动位置监控并且在应用程序移至后台时不执行任何操作,那么您将继续接收位置更新。

关于ios - 当应用程序处于后台或被杀死时如何定期获取新位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41524922/

相关文章:

ios - 迁移到 swift 3 和 Xcode 8 时 cocoa pods 错误的解决方案是什么,问题详情在描述中?

iOS 10 的 Facebook 登录问题

ios - 处理旋转时更改 iOS 键盘布局

parameters - 如何在 Alamofire, swift 3 中将字典作为参数发送

ios - 接受推送通知时会调用什么方法?

swift - 使用 sqlite.swift 过滤多列?

iphone - 如何将新数据保存到现有单元格中?

ios - 为 TextField App 启用安全文本输入后,在构建项目表单 XCode 8 中崩溃

objective-c - ipad编程指导

c# - 将多个 ContentView 放在一个 ScrollView 中