需求
現在做的是一個物流項目,其中用戶端需要獲取到車輛的定位信息,結束後繪製成行車軌跡.後臺實時上傳也就成了一個重要的技術點.
注意點
- 如果車輛行駛過程中,每隔一段時間上報一次.
- 如果車輛速度緩慢,根據移動距離上報
- 如果車輛在某地停留,或者送達後停止上報
- APP被用戶退出或者被系統kill需要繼續上報,應用重新打開後重新上報
<!--more-->
準備工作
在target的Capabilities選項中打開Background Modes 並勾選Location updates 然後在plist中添加Always Usage Description的鍵 在value中隨便鍵入任何內容 requestAlwaysAuthorization支持Region Monitoring和Significant Location Changes 定位工具類
class RCLocationManger: NSObject {
fileprivate var minSpeed : Double = 3
fileprivate var minFilter : Double = 50
fileprivate var minInteval : Double = 10
static let rcLocationManger = RCLocationManger()
fileprivate var manager : CLLocationManager = {
let manager = CLLocationManager()
manager.requestAlwaysAuthorization()
manager.desiredAccuracy = kCLLocationAccuracyBest
return manager
}()
func start(){
manager.distanceFilter = 10
manager.delegate = self
manager.startUpdatingLocation()
}
func startMonitoring() -> () {
manager.startMonitoringSignificantLocationChanges()
}
func stop() {
manager.stopUpdatingLocation()
}
}
擴展
// MARK: - *** 擴展 ***
extension RCLocationManger {
//計算上報條件
func caculateFilter(location : CLLocation) -> () {
//慢速
if location.speed < self.minSpeed {
//距離
if fabs(self.manager.distanceFilter - self.minFilter) > 0.1 {
self.manager.distanceFilter = minFilter
}
} else {
let lastSpeed = self.minFilter / self.minFilter
if fabs(lastSpeed - location.speed) / lastSpeed > 0.1 || lastSpeed < 0 {
let newSpeed = location.speed + 0.5
let newFilter = newSpeed * self.minInteval
self.manager.distanceFilter = newFilter
}
}
}
// 可在此處上傳定位
func saveLocation(location : CLLocation){
//使用realm數據庫保存
let realm = try! Realm()
let loc = LocationModel(value: [location.coordinate.latitude, location.coordinate.longitude, location.timestamp])
try! realm.write {
realm.add(loc)
}
}
}
爲了能夠正確的在被殺掉的情況下被喚醒 我們還要做最後一步操作 在AppDelegate的didFinishLaunchingWithOptions中加入下面的代碼
extension AppDelegate {
func configLocation(launchOptions: [UIApplicationLaunchOptionsKey: Any]?){
if (launchOptions?[UIApplicationLaunchOptionsKey.shortcutItem]) != nil {
RCLocationManger.rcLocationManger.startMonitoring()
}
}
}
Realm數據庫集成
步驟
- 拷貝Realm 和RealmSwift兩個Framework到工程
- 添加libc++庫
- 點擊build Phases左上角+號 選擇new copy file phases 把destination 改成 framework
- 最後把兩個Framework拷貝進去
不然可能會報這個錯如果報這個錯Reason: image not found
測試結果