需要讓APP像Nike+或RunKeeper那樣,就算將APP退到背景,也會持續記錄GPS位置。
但是不知道為什麼在背景執行了20分鐘就停止了。研究後發現原來少了一行關鍵程式。
locationManager.pausesLocationUpdatesAutomatically = false
是否讓位置更新自動停止 ,預設為true
時間到了20分鐘左右,就會自動停止
完整範例下載
以下簡介一下程式的內容,完整程式請直接下載範例
設定APP權限
Capabilities->Background Modes 選擇 ON
勾選 Location updates
加入GPS相關函式庫
General->Linked Frameworks and Libraries
點選 + ,加入 CoreLocation.framework
因為是Swift的關係,需要加入Header File
檔案的內容加上
#import <CoreLocation/CoreLocation.h>
建立Header檔案的關聯
Build Settings-> Swift Compiler-Code Generation
->Objective-C Bridging Header 填入 LocationTrack/Header.h
LocationTrack為專案資料夾
Header.h是剛剛建立的Header File
編輯請求權限時的說明文字
編輯Info.plist
加入 NSLocationAlwaysUsageDescription
裡面的文字,是APP請求相關權限時,向使用者說明的文字內容
以下兩個選擇其中一個填入,差別在於,一個是向使用者請求APP使用期間時,才使用GPS;一個是不管是不是APP使用期間,都可以使用GPS
NSLocationWhenInUseUsageDescription APP使用期間才使用GPS的文字說明
NSLocationAlwaysUsageDescription 任何時間都可以使用GPS的文字說明
向使用者請求權限的畫面
權限的差別
設定->隱私權->定位服務
可以看到兩個權限的差別
當APP的權限是選擇"使用App期間"才可以使用GPS時
將APP退到背景時,會顯示正在使用您的位置
像Nike+和RunKeeper
在程式中,要求請求權限的部份,以下選擇一個就可以了
//在APP使用期間才能使用GPS
locationManager.requestWhenInUseAuthorization()
//隨時都可以使用GPS
locationManager.requestAlwaysAuthorization()
範例APP簡介
這個APP在點選"START開始記錄座標"按鈕時,會開始記錄GPS
把GPS資料寫入GPSRecord.plist檔案裡
在開啟APP時,會先讀取GPSRecord.plist檔案的內容
使用iTools等工具就可以將這個記錄檔案取出
初始化
在ViewController當中先定義一些變數
並加上CLLocationManagerDelegate
初始化CLLocationManager
@IBAction func btnStartGPS(sender: UIButton) { let btnStartGPSLabel: String = btnStartGPS.titleLabel!.text! if((btnStartGPSLabel).rangeOfString("START")?.startIndex == (btnStartGPSLabel).startIndex){ //簡易的判斷現在是要停止或是開始 btnStartGPS.setTitle("STOP停止記錄座標", forState: UIControlState.Normal) //初始化變數 locationManager = CLLocationManager() locationManager.delegate = self //設定精確度 locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation //相當重要的一行 //如果不加的話,會在背景執行20分鐘左右,就停止記錄了 locationManager.pausesLocationUpdatesAutomatically = false if #available(iOS 9.0, *){ locationManager.allowsBackgroundLocationUpdates = true } //---請求權限--- //在APP使用期間才能使用GPS //locationManager.requestWhenInUseAuthorization() //隨時都可以使用GPS locationManager.requestAlwaysAuthorization() //---------- //設置距離篩選器,表示設備至少移動?米,才通知委託更新 locationManager.distanceFilter = 10 locationManager.startUpdatingLocation() }else{ btnStartGPS.setTitle("START開始記錄座標", forState: UIControlState.Normal) locationManager = nil } }
座標更新的事件
//座標有更新時會呼叫這裡 func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { //經緯度 var userLocationLat: String = String(locations[0].coordinate.latitude) var userLocationLon: String = String(locations[0].coordinate.longitude) var GPSText = getNowTime() + "=>" + userLocationLat + "," + userLocationLon textGPS.text = GPSText + "\n" + textGPS.text setPlistContent(GPSText) }需要設定BackgroundTask,才可以在背景執行
override func viewWillAppear(animated: Bool) { myTimer.invalidate() //停止背景執行 backgroundTask = UIBackgroundTaskInvalid } override func viewWillDisappear(animated: Bool) { //當程式進入背景時,執行這段 //這段是測試用,可以不用有這段 //監控APP是否還有在執行 myTimer.invalidate() myTimer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "timerMethod:", userInfo: nil, repeats: true) //加這個,才會在背景執行 //時間到了會執行這裡 backgroundTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler { [unowned self] in } assert(backgroundTask != UIBackgroundTaskInvalid) }
完整範例下載
------------
iOS后台持续定位并定时上传