CoreLocation
是iOS中一個提供設備位置的框架。經過這個框架能夠實現定位處理,獲取位置數據。位置數據一般包括經度,緯度,海拔信息等。ios
iOS8系統下使用定位服務必須在info.plist
文件中添加兩個變量NSLocationAlwaysUsageDescription
和NSLocationWhenInUseUsageDescription
,這兩個Key的值,將分別用於描述應用程序始終使用和使用期間使用定位的說明。git
NSLocationAlwaysUsageDescription
String 應用程序始終使用定位服務github
NSLocationWhenInUseUsageDescription
String 使用應用程序期間,可使用定位服務swift
屬性名 | 描述 |
---|---|
location:CLLocation | 位置 |
desiredAccuracy:CLLocationAccuray | 位置精度 |
func startUpdatingLocation() | 開啓更新位置 |
func stopUpdatingLocation() | 中止更新位置 |
func startUpdatingHeading() | 開啓更新方向 |
func stopUdatingHeading() | 中止更新方向 |
desiredAccuracy屬性 | 描述 |
---|---|
let kCLLocationAccuracyBestForNavigation: CLLocationAccuracy |
精度最高,通常用於導航 |
let kCLLocationAccuracyBest: CLLocationAccuracy |
精度最佳 |
let kCLLocationAccuracyNearestTenMeters: CLLocationAccuracy |
精確度10米內 |
let kCLLocationAccuracyHundredMeters: CLLocationAccuracy |
精確度100米內 |
let kCLLocationAccuracyKilometer: CLLocationAccuracy |
精確度1000米內 |
let kCLLocationAccuracyThreeKilometers: CLLocationAccuracy |
精確度3000米內 |
對於管理器啓動更新後,更新將不斷傳遞給位置管理器委託,直到更新結束。咱們沒法直接控制位置管理器更新的頻率,但能夠用位置管理器的distanceFilter
屬性進行間接控制。在啓動更新前設置屬性distanceFilter
,它指定設備移動多少米後纔將另外一個更新發給委託。定位要求的精度越高、屬性distanceFilter
的值越小,應用程序耗電量就越大。他的單位是米,咱們能夠直接使用整型數字來設置這個距離.數組
locationManager.distanceFilter = 200
發出受權申請,設備會彈出提示,請求用戶容許使用定位服務。代碼以下:網絡
locationManager.requestAlwaysAuthorization()
經過didChangeAuthorizationStatus
代理方法,能夠獲取設備是否容許使用定位服務,代碼以下app
func locationManager(_ manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus){ if status == .NotDetermined || status == .Denied{ //容許使用定位服務 //開始啓動定位更新服務 locationManager.startUpdatingLocation() print("開始定位") } }
startUpdatingLocation
方法啓動定位管理,若是咱們不須要更新定位時,能夠經過stopUpdatingLocation
方法來關閉定位管理,這樣能夠節省電量。框架
locationManager.stopUpdatingLocation()
this
對於委託類CLLocationManagerDelegate
最經常使用的方法是:編碼
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
定位改變時委託執行這個方法,能夠獲得新位置,舊位置。location數組裏會有先後位置的經度緯度座標值。
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){ var currlocation:CLLocation //獲取最新座標 currlocation = locations.last as! CLLocation //獲取經度 currlocation.coordinate.longitude //獲取緯度 currlocation.coordinate.latitude //獲取海拔 currlocation.altitude }
CLLocation對象包含定位點的相關位置數據,主要有經度、緯度、海拔信息、能夠經過屬性和方法來獲取。
屬性名 | 功能 |
---|---|
var coordinate: CLLocationCoordinate2D { get } | 位置的緯度和經度 |
var altitude: CLLocationDistance { get } | 位置海拔 |
var horizontalAccuracy: CLLocationAccuracy { get } | 位置的水平精度 |
var verticalAccuracy: CLLocationAccuracy { get } | 位置垂直精度 |
var speed: CLLocationSpeed { get } | 位置的方向 |
var course: CLLocationDirection { get } | 位置的速度 |
func distanceFromLocation(_ location: CLLocation) -> CLLocationDistance | 兩個位置之間的距離 |
使用`func locationManager(_ manager: CLLocationManager,
didUpdateHeading newHeading: CLHeading)`能夠獲取到設備移動的方向。參數`newHeading`是一個CLHeading對象。CLHeading經過一組屬性來提供航向讀數:
magneticHeading
和trueHeading
。這些值的單位爲度。類型爲CLLocationDirection
,即雙精度浮點數。這意味着:
若是航向爲0.0,則前進方向爲北
若是航向爲90.0,則前進方向爲東
若是航向爲180.0,則前進方向爲南
若是航向爲270.0,則前進方向爲西
magneticHeading
和trueHeading
分別表示磁性航向,和真實航向。若是位置服務被關閉了,GPS和WIFI就只能獲取磁場航向。只有打開位置服務,才能獲取真實航向。
須要注意,在使用代理前,須要開啓更新方向:
locationManager.startUpdatingHeading()
屬性名 | 描述 |
---|---|
magneticHeading | 位置的磁極方向 |
trueHeading | 位置的真實方向 |
headingAccuracy | 方向經度 |
timestamp | 時間戳 |
description | 獲取方向數據 |
當定位失敗時就會調用委託方法
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) { //錯誤處理 當地位出錯時調用 if let clerr = CLError(rawValue: error.code){ } } //CLError 是一個每枚舉類型 public enum CLError : Int { case LocationUnknown // location is currently unknown, but CL will keep trying // 目前未知,請努力獲取 case Denied // Access to location or ranging has been denied by the user // 獲取位置功能被拒絕使用 case Network // general, network-related error //網絡錯誤 case HeadingFailure // heading could not be determined //獲取的位置標題信息,不能肯定 case RegionMonitoringDenied // Location region monitoring has been denied by the user //位置區域已被用戶監測 case RegionMonitoringFailure // A registered region cannot be monitored //監測器不能註冊 case RegionMonitoringSetupDelayed // CL could not immediately initialize region monitoring //不能初始化檢測器 case RegionMonitoringResponseDelayed // While events for this fence will be delivered, delivery will not occur immediately //區域檢測器響應延遲 case GeocodeFoundNoResult // A geocode request yielded no result //地理編碼無結果 case GeocodeFoundPartialResult // A geocode request yielded a partial result //地理編碼請求獲得部分結果 case GeocodeCanceled // A geocode request was cancelled //地理編碼 請求被取消 case DeferredFailed // Deferred mode failed //推遲模式失敗 case DeferredNotUpdatingLocation // Deferred mode failed because location updates disabled or paused //因爲位置更新失敗或者暫停,推遲模式失敗 case DeferredAccuracyTooLow // Deferred mode not supported for the requested accuracy //推遲模式不支持經度要求 case DeferredDistanceFiltered // Deferred mode does not support distance filters //推遲模式沒法支持距離濾波器 case DeferredCanceled // Deferred mode request canceled a previous request //推遲模式被取消 case RangingUnavailable // Ranging cannot be performed //沒法進行測距 case RangingFailure // General ranging failure //通用測距故障 }
更多代理的方法請看文檔。
經過Core Location類獲得的地位信息都是以經度和緯度等表示的地理信息。通常都須要反編碼城一個地址。
這就須要CLGeocoder
類來實現地理信息反編碼
// 1. 實例化定位管理器 _locationManager = [[CLLocationManager alloc] init]; // 2. 設置代理 _locationManager.delegate = self; // 3. 定位精度 [_locationManager setDesiredAccuracy:kCLLocationAccuracyBest]; // 4.請求用戶權限: //分爲: //⓵只在前臺開啓定位 //⓶在後臺也可定位, //注意:建議只請求⓵和⓶中的一個,若是兩個權限都須要,只請求⓶便可, //⓵⓶這樣的順序,將致使bug:第一次啓動程序後,系統將只請求⓵的權限,⓶的權限系統不會請求,只會在下一次啓動應用時請求⓶ if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) { //[_locationManager requestWhenInUseAuthorization];//⓵只在前臺開啓定位 [_locationManager requestAlwaysAuthorization];//⓶在後臺也可定位 } // 5.iOS9新特性:將容許出現這種場景:同一app中多個location manager:一些只能在前臺定位,另外一些可在後臺定位(並可隨時禁止其後臺定位)。 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) { _locationManager.allowsBackgroundLocationUpdates = YES; } // 6. 更新用戶位置 [_locationManager startUpdatingLocation];
對應的 Info.plist 的XML源碼是:
<key>NSLocationAlwaysUsageDescription</key> <string>請求後臺定位權限</string> <key>UIBackgroundModes</key> <array> <string>location</string> </array>
在對應 target 的 Capabilities -> Background Modes -> 開啓 Location Updates
例子:
typealias CoreLocationdelegate = ViewController extension CoreLocationdelegate:CLLocationManagerDelegate{ func configLocation(){ //1 the location manager let locationManager = CLLocationManager() //2 setting the desired accuracy locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest //3 setting the distance filter locationManager.distanceFilter = 1000 //4 getting permission to use location services locationManager.requestAlwaysAuthorization() //5 starting the location manager } func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { //獲取設備是否容許使用定位服務 if status == CLAuthorizationStatus.Denied || status == CLAuthorizationStatus.NotDetermined{ locationManager.requestAlwaysAuthorization() }else{ //容許使用定位服務的話,開啓定位服務更新 locationManager.startUpdatingLocation() //開啓方向更新服務 locationManager.startUpdatingHeading() } } func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){ //獲取最新的座標 let theLocation = locations.last //獲取緯度 let latitude = theLocation?.coordinate.latitude //獲取經度 let longitude = theLocation?.coordinate.longitude //獲取海拔 let altitude = theLocation?.altitude } func locationManager(manager: CLLocationManager, didFailWithError error: NSError) { //錯誤處理 當地位出錯時調用 if let clerr = CLError(rawValue: error.code){ } } func locationManager(manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) { //能夠獲取設備移動的方向 }