在Swift 2.0中每隔n分钟更新一次背景中的位置
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Swift 2.0中每隔n分钟更新一次背景中的位置相关的知识,希望对你有一定的参考价值。
使用AppDelegate.swift中的以下代码,我可以每30秒获得一次位置更新。但是,在180秒后,backgroundTimeRemaining将执行后台执行。 plist在UIBackgroundModes中具有“location”标记 我有两个问题:
- 为什么backgroundTimeRemaining没有重置?
- 如果我执行startUpdatingLocation()然后stopUpdatingLocation()以节省电池,那么我将无法再次更新位置。
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后解决了问题。
答案
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()
}}
我添加了sleep函数来延迟调用该位置并将信息发送到服务器
由于这是在应用程序处于活动状态并且转到后台运行。如果只需要后台进程,请从didFinishLaunchingWithOptions中删除或注释函数self.doBackgroundTask(),并在applicationdidEnterBackground中删除self.doBackgroundTask()的注释。然后删除函数bgtimer()中的注释,因为一旦应用程序进入活动状态,后台进程就必须停止。
谢谢你只使用你的代码我能够为持续运行提供一些替代解决方案。
以上是关于在Swift 2.0中每隔n分钟更新一次背景中的位置的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iOS 应用程序中每 n 分钟获取一次后台位置更新?