CoreLocation定位

CoreLocation是iOS中一個提供設備位置的框架。經過這個框架能夠實現定位處理,獲取位置數據。位置數據一般包括經度,緯度,海拔信息等。ios

iOS8系統下使用定位服務必須在info.plist文件中添加兩個變量NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription,這兩個Key的值,將分別用於描述應用程序始終使用和使用期間使用定位的說明。git

NSLocationAlwaysUsageDescription String 應用程序始終使用定位服務github

NSLocationWhenInUseUsageDescription String 使用應用程序期間,可使用定位服務swift

CLLocationManager屬性和方法

屬性名 描述
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對象包含定位點的相關位置數據,主要有經度、緯度、海拔信息、能夠經過屬性和方法來獲取。

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經過一組屬性來提供航向讀數:

magneticHeadingtrueHeading。這些值的單位爲度。類型爲CLLocationDirection,即雙精度浮點數。這意味着:

若是航向爲0.0,則前進方向爲北

若是航向爲90.0,則前進方向爲東

若是航向爲180.0,則前進方向爲南

若是航向爲270.0,則前進方向爲西

magneticHeadingtrueHeading分別表示磁性航向,和真實航向。若是位置服務被關閉了,GPS和WIFI就只能獲取磁場航向。只有打開位置服務,才能獲取真實航向。

須要注意,在使用代理前,須要開啓更新方向:

locationManager.startUpdatingHeading()

CLHeading屬性

屬性名 描述
magneticHeading 位置的磁極方向
trueHeading 位置的真實方向
headingAccuracy 方向經度
timestamp 時間戳
description 獲取方向數據

CLError

當定位失敗時就會調用委託方法

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類來實現地理信息反編碼

iOS9新特性 更靈活的後臺定位(摘自)

請求後臺定位權限:

方法一

// 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) {
       //能夠獲取設備移動的方向


   }
相關文章
相關標籤/搜索