CoreLocation 框架


獲取設備的地理位置和方向


一.概述

CoreLocation框架,它提供了如下幾種服務

  • 確定設備的地理位置
  • 高度
  • 方向
  • 或到附近 iBeacon 的相對位置.

這個框架使用所有可用的車載硬件.如 Wi-Fi, GPS, 藍牙, 磁強計, 氣壓計,和蜂窩硬件來收集數據.

在申請許可和確定服務可用之后,對於絕大部分的服務,你都會用 CLLocationManager 這個對象來啟動.並接收那些關聯代理對象的結果.


二.Symbols

第1步:

1>CLLocationManager

位置管理者,用來將與位置相關的事件交付給 App .

1.使用這個類的實例來建立參數

  • 用來確定什么時候應該交付位置和標題事件.並啟動這些交付事件
  • 並且在不需要位置數據時停止交付
  • 還可以檢索最新的位置和標題數據

2.CLLocationManager 對象支持如下活動:

  • 跟蹤用戶當前位置變化,可配置精確度
  • 確定航向的變化(船上.僅僅限於 iOS)
  • 區域監聽.(用戶進入或離開這些區域時均可生成位置事件)
  • 當程序退到后台時,延遲交付位置的更新(僅限於 iOS)
  • 向附近的iBeacons報告范圍

3.配置並使用 CLLocationManager 對象來交付事件

  • 始終請求授權使用位置服務.並檢查在請求使用位置服務時,在<請求使用位置服務>章節處描述的所需服務是否可用
  • 創建一個 CLLocationManager 的實例,並對它強引用.
    • 在所有涉及到該對象的任務完成之前,必須保持對該對象的強引用.因為絕大部分的位置管理者任務都是異步運行的,所以將該對象存在本地變量中是不夠的
  • 自定義對象使用代理時,必須遵守其對應的協議
  • 配置和服務相關的其他屬性
  • 適當的時候,調用 start 方法,開始事件交付.

代理方法可以監聽到所有的位置和標題的變化.

4.請求使用位置服務

使用位置服務要先請求用戶授權.此外,某些位置服務要求特定機型存在特定硬件.在使用位置服務之前,必須請求授權和檢查目標服務是否可用.

[1]獲取當前 App 的授權狀態

此授權狀態由系統管理,由若干因素決定.當應用程序第一次使用位置服務時,將會自動顯示用戶授權請求.

+ (CLAuthorizationStatus)authorizationStatus;

// 家長控制模式,不允許使用位置服務
KCLAuthorzationStatusRestricted
// 用戶明確拒絕使用位置服務
KCLAuthorizationStatusDenied

[2]創建 CLLocationManager 對象,並設置 delegate

[3]對 CLLocationManager 對象保持強引用

[4]在 iOS 中,如果授權狀態是 KCLAuthorizationStatusNotDetermined = 0(用戶未作出選擇), 那么就可以使用如下兩種模式供用戶選擇

  • 請求前台服務
    • 此方法異步執行.

    • 要在 info.plist 中配置相應的 key : NSLocationWhenInUseUsageDescription

    • 狀態確定之后, CLLocationManager 將結果發送給下面這個代理方法

      - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status;
      
- (void)requestWhenInUseAuthorization
  • 請求前后台服務
    • info.plist 配置key : NSLocationAlwaysUsageDescription
    • 這種模式因為會對用戶隱私有潛在的影響,所以一般會被用戶阻止,只有真正對用戶有好處時才應該請求這種授權.
- (void)requestAlwaysAuthorization;

[5]根據你需要的服務,調用以下方法

  • 標准定位服務(可以作為開啟定位服務的開關)
+ (BOOL)locationServicesEnabled;
  • 重要位置更改跟蹤
    • 此方法指示設備是否能夠僅基於重要位置更改報告更新。這種功能提供了巨大的功率節省的應用程序,要跟蹤用戶的大致位置,不需要高度准確的位置信息。
+ (BOOL)significantLocationChangeMonitoringAvailable;
  • 標題信息
+ (BOOL)headingAvailable;
  • 檢查某個指定的類支持區域監聽
    • 區域監聽取決於設備上的硬件.這個方法並沒有考慮位置服務是否可用及用戶是否禁用問題.所以你必須要單獨確認授權狀態
+ (BOOL)isMonitoringAvailableForClass:(Class)regionClass;
  • 檢查設備是否支持藍牙信標的測距
+ (BOOL)isRangingAvailable;

5.在確定應用程序的授權狀態之前,啟動位置服務是安全的.雖然可以啟動位置服務,但這些服務不提供任何數據.直到授權狀態變為KCLAuthorizationStatusAuthorizedAlwaysKCLAuthorizationStatusAuthorizedWhenInUse.實現 CLLocationManager 的代理方法 locationManager:didChangeAuthorizationStatus:可以監聽到授權狀態的變化.

6.我們也可以准確的來配置該服務相關聯的屬性.以便在定位的核心位置不需要時,可以關閉,來節省電量.如精確到一公里.那么就可以關閉GPS硬件,僅僅依賴Wi-Fi或單元無線電,這樣會省很多功率

5.獲取用戶當前位置

1.有兩種配置方案:

  • 第一是使用標准定位服務.它允許您指定所需的位置數據的准確性.並隨着位置的變化而接收更新.

    • 定位數據的准確性
    @property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;
    
    • 當前位置與下一個更新位置的最小距離
    @property(assign, nonatomic) CLLocationDistance distanceFilter;
    
    • 請求用戶當前位置
    - (void)requestLocation;
    
    • 開始更新用戶位置
    - (void)startUpdatingLocation;
    
    • 推遲交付更新位置,直到滿足指定的標准為止
    - (void)allowDeferredLocationUpdatesUntilTraveled:(CLLocationDistance)distance timeout:(NSTimeInterval)timeout;
    

    精確度越高越費電.

  • 第二是使用重要位置更改服務.它提供了一個比較有限的跟蹤選項,但節能.在 iOS 中,該服務還可以根據需要啟動應用程序以提供位置更新.

    • 適合那些希望獲得用戶初始位置的應用程序,然后只想知道該位置如何改變.
    • 需要蜂窩硬件的存在
    • 比標准定位服務更加頻繁的交付事件
    • 開啟方法
    - (void)startMonitoringSignificantLocationChanges;
    
  • 不管您使用哪種位置服務,位置數據都通過位置管理器的關聯委托對象報告給您的應用程序。由於返回初始位置可能需要幾秒鍾,位置管理器通常會立即發送以前緩存的位置數據,然后在可用時提供更多的最新位置數據。因此,在采取任何操作之前,檢查任何位置對象的時間戳總是一個好主意。如果兩個位置服務同時啟用,則它們使用同一組委托方法交付事件。

  • 使用推遲更新的那個方法時,可以節省能源,如在跟蹤用戶一個遠程路線的時候,可以推遲更新,直到用戶提高了一定的距離,然后一次性處理這些點即可

6.區域監聽

當用戶跨越區域邊界時,我們可以監聽到.

1.區域監聽適用於地理區域 (代表的類如: CLCircularRegion) 和 信標區 (代表類如: CLBeaconRegion)

2.使用區域監聽監測指定區域的交叉點,並執行相關的任務.如接近干洗店時, App 通知用戶取走已經洗好的衣服.

3.開始監聽指定區域

必須為每個要監視的區域調用此方法一次.如果應用程序已經監視同一標識符的現有區域.則舊區域被新的區域替換.

所有位置管理器對象監視的共享區域集

@property(readonly, nonatomic, copy) NSSet<__kindof CLRegion *> *monitoredRegions;

開始監聽指定區域方法

- (void)startMonitoringForRegion:(CLRegion *)region;

[1].告訴代理,用戶進入指定區域

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region;

[2].告訴代理用戶離開指定區域

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region;

[3].告訴代理,區域監視錯誤

- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error;

4.如果程序未運行時發生區域越界.系統會自動將他喚醒.然后它可以處理事件.在這種情況下,為了表名您的應用程序時因為與位置相關的事件而啟動的,將UIApplicationLaunchOptionsLocationKeykey傳給application:didFinishLaunchingWithOptions:方法.在重啟的過程中,必須創建一個位置管理者對象和分配一個能夠處理區域相關的事件代理.做完這些之后,系統就會發送應用程序啟動的區域通知.

5.區域監視服務獨立於應用程序使用的任何位置服務,你可以與其他服務一起使用.使用如下方法,檢測區域監視是否可用

+ (BOOL)regionMonitoringAvailable;

7.確定接近 Beacons

1.創建一個CLBeaconRegion對象.

2.開始為指定區域中的信標發出通知

- (void)startRangingBeaconsInRegion:(CLBeaconRegion *)region;

3.告訴代理一個或多個信標在范圍內

- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region;

8.配置與標題相關的服務.

開始生成報告用戶當前標題的更新

- (void)startUpdatingHeading;

9.獲取訪問的位置

訪問服務為應用程序的重要位置更改服務提供了另一種選擇,這需要用戶訪問的興趣點的位置信息.舉個例子,如果一個用戶在一個位置上滯留延長了一段時間,當用戶到達該位置時,該服務可能生成一個事件,當用戶離開這個位置又生成另一個事件,這個服務是為了那些可能已經在使用重要位置更改服務的同時又想要一個更低功率的方案的應用程序而設計的.

這個方案不能用來做導航和那種依靠定期的位置更新的 App.

啟動訪問事件的發生

- (void)startMonitoringVisits;

代理方法 : 告訴代理收到了一個新的訪問事件

- (void)locationManager:(CLLocationManager *)manager didVisit:(CLVisit *)visit;

10.在后台使用位置服務

大多數的位置服務都是在前台使用的,但是有些也需要在后台使用.要使用后台位置服務,必須先向用戶請求Always授權.

  • 通常標准定位服務只是服務於前台運行的應用程序.當我們的應用程序處於后台運行模式下,只有 App 啟用后台位置更新服務的時候,它才會有效.當一個程序終止的時候,它不會重新啟動該應用程序.
  • 通常重要位置更新服務會傳遞事件,當應用程序處於前后台運行模式下時.當程序終止時,這個服務會重啟應用程序並發送事件.使用這個服務的話要用戶的Always授權.
  • 當應用程序處於前后台模式下,區域監聽可以發送事件.當程序終止時,也可以重新喚醒它.同樣,它也需要獲取用戶的Always授權
  • Beacon 一般只有當 App 前台運行的時候才有效.當 App 運行到后天模式的情況下.只有當后台位置更新服務有效的時候並且標准定位服務開啟的時候,它才會有效.它不會喚醒已經終止的應用程序.然后,你可以重新利用區域監測服務監測信標地區.
  • 標題服務一般只會在前台模式下才交付事件.當應用程序后台運行時,它也是需要開啟后台服務模式並且開啟標准定位服務才有效.它同樣不會喚醒已經終止的應用程序.
  • 訪問服務也是一般用在前台服務.當程序運行在后台模式下,同樣需要開啟后台服務和開啟標准定為模式.但是,對於一個已經終止的應用程序來說,它可以喚醒這個應用程序.使用這個服務,需要用戶的Always授權.

啟用后天定位服務可以確保 App 在后台的時候依然可以接收位置事件.當應用程序退到后台的時候,系統會將這個指示器添加到狀態欄位置,使用戶知道我們的應用程序正在使用位置服務.當然,系統可以在任何時候來終止應用程序來回收內存或其他資源.

Note
在 iOS 8之后.禁用當前的應用程序或所有的應用程序的"后天應用程序的刷新"設置不會阻止后台事件的交付.在之前的版本中,禁用后天應用程序刷新的設置就會阻止后台事件的傳遞.

當重啟App時,系統會將UIApplicationLaunchOptionsLocationKey這個key發給 App 的代理.當這個密鑰存在的時候,您應該立即重啟您的應用程序的位置服務.這個選項字典不包含關於事件本身的信息.所以你必須要重新配置一個 CLLocationManager 對象和 delegate 並且重啟位置服務來接收所有被掛起的事件.在 iOS 7.1 之后.那些被用戶強制退出的App也會受到這一服務.在之前的版本不可以.

如果你的應用程序不需要實時更新的位置信息.那么就用如下的方法,延遲位置更新的交付.這樣會更加的省電.同時也滿足我們應用程序的位置服務功能.

- (void)allowDeferredLocationUpdatesUntilTraveled:(CLLocationDistance)distance timeout:(NSTimeInterval)timeout;

11.一些方法

[1]請求定位服務的授權

請求前台授權

- (void)requestWhenInUseAuthorization;

說明 :

如果當前的授權狀態是 KCLAuthorizationStatusNotDetermined.那么這個方法是異步的,並且提示用戶對該應用程序啟用位置服務權限.同時當狀態確定之后,位置管理者會通過如下的代理方法來接收結果.如果當前的狀態不是這個的話,那么此方法什么都不會做.並且不會調用代理方法做事情.

應該在 info.plist文件中,配置NSLocationWhenInUseUsageDescription key.

代理方法:

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status;

在使用位置服務之前,你必須調用requestWhenInUseAuthorization這個方法或者requestAlwaysAuthorization這個方法.如果啟用when-in-use這個授權,那么就是指前台服務.在前台可以獲取到用戶的位置信息,在后台默認的情況下無法獲取用戶的位置信息.要開啟后台模式.但是系統會在狀態欄位置顯示一個藍色的橫幅,提示用戶我們在使用后台服務.

請求前后台定位授權

- (void)requestAlwaysAuthorization;

同樣,狀態是KCLAuthorizationStatusNotDetermined的時候.提示用戶開啟定位服務權限.

info.plist中配置keyNSLocationAlwaysUsageDescription.狀態確定之后,也會調用上面的那個代理方法來接收結果.如果狀態不是的話,也不會執行該方法.

請求always授權會對用戶的隱私有一定的影響.一般都會被用戶所阻止.所以建議只有真正的對用戶有好處的情況下.才應該請求這種授權.

請求這種授權模式,在前后台都可以獲取用戶的位置信息.而且不需要開啟后台模式.也沒有藍色的橫幅來提示用戶.

[2]確定服務的可用性

一共有7個方法

// 1.返回應用程序使用位置服務的授權狀態
+ (CLAuthorizaationStatus)authorizationStatus;

// 2.是否在設備上啟用位置服務
+ (BOOL)locationServicesEnabled;

// 3.設備是否支持延遲位置更新
+ (BOOL)deferrdLocationUpdatedsAvailable;

// 4.是否有重要位置更改跟蹤可用
+ (BOOL)significanfLocationChangeMonitoringAvailable;

// 5.位置管理者是否可以生成與標題相關的事件
+ (BOOL)headingAvailable;

// 6.指定的類是否支持區域監聽
+ (BOOL)isMonitoringAvailableForClass:(Class)regionClass;

// 7.設備是否支持 藍牙信標
+ (BOOL)isRangingAvailable;
[3]訪問授權

接收更新事件的代理

@property(assign, nonatomic) id<CLLocationManagerDelegate> delegate;
[4]啟動標准定位服務

3個方法.5個屬性

// 1.開始更新用戶當前位置信息
- (void)startUpdatingLocation;

// 2.停止更新位置變化信息
- (void)stopUpdatingLocation;

// 3.獲取用戶當前位置,
- (void)requestLocation;

// 4.指示位置管理者對象是否可以暫停位置更新
@property (assign, nonatomic) BOOL pausesLocationUpdatesAutomatically;

// 5.指示應用程序是否希望在暫停的時候接收位置更新
@property (assign, nonatomic) BOOL allowsBackgroundLocationUpdates;

// 6.在生成更新事件之前設備必須水平移動的最小距離(以m計)
@property (assign, nonatomic) CLLocationDistance distanceFilter;

// 7.定位數據的精確度
@property (assign, nonatomic) CLLocationAccuracy desiredAccuracy;

// 8.與位置更新相關聯的用戶活動類型
@property (assign, nonatomic) CLActivityType activityType;
[5]啟動重要位置更新
// 1.開始更新重要位置
- (void)startMonitoringSignificantLocationChanges;

// 2.停止更新
- (void)stopMonitoringSignificantLocationChanges;
[5]啟動標題更新
// 1.開始更新用戶當前的標題
- (void)startUpdatingHeading;

// 2.停止更新
- (void)stopUpdatingHeading;

// 3.立即從屏幕上取消標題校准視圖
- (void)dismissHeadingCalibrationDisplay;

// 4.生成新的標題事件所需的最小角度變化(以度為單位)
@property (assign, nonatomic) CLLocationDegrees headingFilter;

// 5.計算航向值時使用的設備方向
@property (assign, nonatomic) CLDeviceOrientation headingOrientation;
[6]啟動區域監聽
// 1.開始監視指定區域
- (void)startMonitoringForRegion:(CLRegion *)region;

// 2.停止監視指定區域
- (void)stopMonitoringForRegion:(CLRegion *)region;

// 3.所有位置管理者對象監視的共享區域集
@property (readonly, nonatomic, copy) NSSet <__kindof CLRegion *> *monitoredRegions;

// 4.可以分配給一個區域的最大的邊界距離
@property (readonly, nonatomic) CLLocationDistance maximumRegionMonitoringDistance;
[7]啟動信標測距請求
// 1.開始為指定區域中的信標發出通知
- (void)startRangingBeaconsInRegion:(CLBeaconRegion *)region;

// 2.停止為指定區域中的信標發出通知
- (void)stopRangingBeaconsInRegion:(CLBeaconRegion *)region;

// 3.異步檢索區域的狀態
- (void)requestStateForRegion:(CLRegion *)region;

// 4.當前使用測距跟蹤的區域集
@property (readonly, nonatomic, copy) NSSet <__kindof CLRegion *> *rangedRegions;
[8]啟動訪問事件更新
// 1. 開始啟動與訪問相關的事件
- (void)startMonitoringVisits;

// 2.開始通知與訪問相關的事件
- (void)stopMonitoringVisits;
[9]延遲位置更新
// 1.延遲位置更新的交付,直到滿足指定的標准為止
- (void)allowDeferredLocationUpdatesUntilTraveled:(CLLocationDistance)distance timeout:(NSTimeInterval)timeout;

// 2.取消這個程序的位置更新的延遲
- (void)disallowDeferredLocationUpdates;
[10]獲取最近檢索到的數據
// 1.最近檢索到的用戶位置
@property (readonly, nonatomic, copy) CLLocation *location;

// 2.最近檢索到的標題
@property (readonly, nonatomic, copy) CLHeading *heading;
[11]過期(廢棄)的屬性和方法
// 1.指示是否在設備上啟用位置服務
@property (readonly, nonatomic) BOOL locationServicesEnabled;

// 2.指示位置管理者是否能夠生成與標題相關的事件
@property (readonly, nonatomic) BOOL headingAvailable.

// 3.指示當前設備是否支持區域監聽
+ (BOOL)regionMonitoringAvailable;

// 4.指示區域監聽是否當前啟用
+ (BOOL)regionMonitoringEnabled;

// 5.開始監視指定區域的邊界交叉點
- (void)startMonitoringForRegion:(CLRegion *)region desiredAccuracy:(CLLocationAccuracy)accuracy;

// 6.描述使用位置服務的原因
@property (copy, nonatomic) NSString *purpose;
[12]常量
// 1.這些常量指示應用程序是否被授權使用位置服務
typedef enum CLAuthorizationStatus : int {
	
	KCLAuthorizationStatusNotDetermined = 0,
	KCLAuthorizationStatusRestricted,
	KCLAuthorizationStatusDenied,
	KCLAuthorizationStatusAuthorizedAlways,
	KCLAuthorizationStatusAuthorizedWhenInUse,
	KCLAuthorizationStatusAuthorized = KCLAuthorizationStatusAuthorizedAlways

} CLAuthorizationStatus;

// 2.設備的物理定向
typedef enum CLDeviceOrientation : int {

	CLDeviceOrientationUnknown = 0,
	CLDeviceOrientationPortrait,
	CLDeviceOrientationPortraitUpsideDown,
	CLDeviceOrientationLandscapeLeft,
	CLDeviceOrientationLandscapeRight,
	CLDeviceOrientationFaceUp,
	CLDeviceOrientationFaceDown

} CLDeviceOrientation;

// 3.與位置更新相關的活動類型

typedef enum CLActivityType : NSInteger {
	
	CLActivityTypeOther = 1,
	CLActivityTypeAutomotiveNavigation,
	CLActivityTypeFitness,
	CLActivityTypeOtherNavigation

} CLActivityType;

// 4.指示所有動作應該被報告的常數.使用這個常量指定的位置,任何的位置更改都會觸發一個新的位置更改
const CLLocationDistance KCLDistanceFilterNone;

// 5.指示所有標頭值應該被報告的常量
const CLLocationDegrees KCLHeadingFilterNone;

// 6.表示最大距離的常數
const CLLocationDistance CLLocationDistanceMax;

// 7.表示無限時間的值
const NSTimeInterval CLTimeIntervalMax;

2>CLLocationManagerDelegate

用於接收來自相關位置管理者對象的事件的方法的協議.

1.概述

如果位置管理者報告了檢索請求數據的問題,您可能希望在短時間內停止更新,然后再試一次.你可以使用 CLLocationManager 的如下這些個方法來停止各種的位置服務.

- (void)stopUpdatingLocation;
- (void)stopMonitoringSignificantLocationChanges;
- (void)stopUpdatingHeading;
- (void)stopMonitoringForRegion:(CLRegion *)region;
- (void)stopMonitoringVisits;

代理對象的方法是從啟動相應位置服務的線程中調用的,該線程本身必須具有一個活動的運行循環.就像在應用程序的主線程中找到的一樣.

2.方法

[1]響應位置事件
// 1.告訴代理可以使用新的位置數據
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations;

// 2.告訴代理位置管理者無法檢索位置的值
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error;

// 3.告訴代理,更新將不再被推遲
- (void)locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error;

// 4.告訴代理可以使用新的位置的值
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation;
[2]暫停的位置更新
// 1.告訴代理,位置更新已暫停
- (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager;

// 2.告訴代理,已經恢復位置更新的交付
- (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager;
[3]對標題事件的響應
// 1.告訴代理位置管理者接收到更新的標題信息
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading;

// 2.詢問代理是否應該顯示標題校准警報
- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager;
[4]響應區域事件
// 1.告訴代理,用戶進入指定區域
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region;

// 2.告訴代理,用戶離開指定區域
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region;

// 3.告訴代理有關指定區域的狀態
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region;

// 4.告訴代理發生了區域監視錯誤
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error;

// 5.告訴代理正在監視新區域
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region;
[5]對測距事件的響應
// 1.告訴代理一個或多個信標在范圍內
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray<CLLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region;

// 2.告訴代理在收集一組信標的測距信息時發生了一個錯誤
- (void)locationManager:(CLLocationManager *)manager rangingBeaconsDidFailForRegion:(CLBeaconRegion *)region withError:(NSError *)error;
[6]響應訪問事件
// 1.告訴代理收到了一個新的與訪問有關的事件
- (void)locationManager:(CLLocationManager *)manager didVisit:(CLVisit *)visit;
[7]響應授權更改
// 1.告訴代理程序更改了授權狀態
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status;

位置更新

1>CLLocation

包含系統報告的維度,經度和航向信息的數據對象

方法

[1]初始化位置對象
// 1.初始化並返回具有指定維度和經度的位置對象
// latitude: 坐標點的維度
// longitude: 經度
- (instancetype)initWithLatitude:(CLLocationDegrees)latitude longitude:(CLLocationDegrees)longitude;

// 2.初始化並返回具有指定坐標信息的位置對象
// coordinate : 包含經緯度值的坐標結構
// altitude : 位置的高度值
// hAccuracy : 坐標值的精度,指定負數表示坐標值無效
// vAccuracy : 高度值的准確定.指定負數表示海拔值無效
// timestamp : 與位置相關聯的時間,通常,您會將此設置為當前時間.
- (instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate altitude:(CLLocationDistance)altitude horizontalAccuracy:(CLLocationAccuracy)hAccuracy verticalAccuracy:(CLLocationAccuracy)vAccuracy timestamp:(NSDate *)timestamp;

// 3.初始化並返回具有指定坐標和課程信息的位置對象
// course : 位置的旅行方向
// speed  : 與此位置相關聯的當前速度
- (instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate altitude:(CLLocationDistance)altitude horizontalAccuracy:(CLLocationAccuracy)hAccuracy verticalAccuracy:(CLLocationAccuracy)vAccuracy course:(CLLocationDirection)course speed:(CLLocationSpeed)speed timestamp:(NSDate *)timestamp;
[2]位置屬性
// 1.地理坐標信息
@property(readonly, nonatomic) CLLocationCoordinate2D coordinate;

// 2.測量的高度(單位:m)
@property(readonly, nonatomic) CLLocationDistance altitude;

// 3.用戶所在的建築物合理層
@property(readonly, nonatomic, copy) CLFloor *floor;

// 4.位置的不確定度半徑(以m為單位)
@property(readonly, nonatomic) CLLocationAccuracy horizontalAccuracy;

// 5.高度值的准確性(單位:m)
@property(readonly, nonatomic) CLLocationAccuracy verticalAccuracy;

// 6.確定這個位置的時間
@property(readonly, nonatomic, copy) NSDate *timestamp;
[3]測量坐標之間的距離
// 返回從接收器位置到指定位置的距離(單位: m)
- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location;

// [過期方法]
- (CLLocationDistance)getDistanceFrom:(const CLLocation *)location;
[4]獲取速度和課程信息
// 1.速度 m/s
@property(readonly, nonatomic) CLLocationSpeed speed;

// 2.裝置行進的方向
@property (readonly, nonatomic) CLLocationDirection course;
[5]數據類型
// 1.設備移動的速度 (單位m/s)
typedef double CLLocationSpeed;

// 2.相對於真北以度測量的方位角
// 方向值是從正北方向開始測量,然后沿着指南針順時針方向繼續.因此,北是0°,東是90°,南是180°,等等.負值表示無效方向
typedef double CLLocationDirection;

2>CLFloor

標識設備所在樓層的樓層的數據對象

3>CLVisit

在特定時間內識別用戶位置的數據對象

封裝有關的用戶得到的興趣點信息.包括訪問發生的地點和有關到達和離開時間的信息.

[1]獲取訪問地點
// 1.地理坐標信息
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

// 2.指定坐標的水平精度(m)
@property (nonatomic, readonly) CLLocationAccuracy horizontalAccuracy;
[2]獲取訪問時間
// 1.用戶到達指定位置的大致時間
@property (nonatomic, readonly, copy) NSDate *arrivalDate;

// 2.用戶離開指定位置的大致時間
@property (nonatomic, readonly, copy) NSDate *departureDate;

4>CLLocationCoordinate2D

// 1.無效的坐標值
const CLLocationCoordinate2D KCLLocationCoordinate2DInvalid;

// 2.指定坐標是否有效
BOOL CLLocationCoordinate2DIsValid(CLLocationCoordinate2D coord);

// 3.將維度和經度值格式化為坐標數據結構格式
CLLocationCoordinate2D CLLocationCoordinate2DMake(CLLocationDegrees latitude,CLLocationDegrees longitude);

// 4.維度
CLLocationDegrees latitude;

// 5.經度
CLLocationDegrees longitude;

5>CLLocationDegrees

在度數上指定的維度或經度值

typedef double CLLocationDegrees;

6>CLLocationDistance

從現有的位置進行的距離測量(m)

typedef double CLLocationDistance;

7>CLLocationAccuracy

坐標值的准確度,以m為單位

typedef double CLLocationAccuracy;

區域監聽

1>CLCircularRegion

由中心點和半徑定義的地理區域.圓形.可以為特定的位置定義地理圍欄.

// 1.初始化並返回定義圓形地理區域的區域對象
// center : 地理區域中心點監測
// radius : 從地理區域中心點到圓形邊界邊緣的距離(m)
// identifier : 與區域對象相關聯的唯一標識符。使用這個標識符來區分應用程序中的區域。此值不能為零
- (instancetype)initWithCenter:(CLLocationCoordinate2D)center radius:(CLLocationDistance)radius identifier:(NSString *)identifier;


// 2.地理區域的中心點
@property(readonly, nonatomic) CLLocationCoordinate2D center;

// 3.定義地理區域外邊界的半徑(m)
@property(readonly, nonatomic) CLLocationDistance radius;

// 4.指示地理區域是否包含指定坐標
- (BOOL)containsCoordinate:(CLLocationCoordinate2D)coordinate;

iBeacon

1>CLBeacon


// 1.信標的接近標識
@property (readonly, nonatomic, copy) NSUUID *proximityUUID;

// 2.信標中最重要的值
@property (readonly, nonatomic, copy) NSNumber *major;

// 3.信標中最不重要的值
@property (readonly, nonatomic, copy) NSNumber *minor;

// 4.信標相對距離
@property (readonly, nonatomic) CLProximity proximity;

// 5.接近值的准確度,從信標測量到m
@property (readonly, nonatomic) CLLocationAccuracy accuracy;

// 6.信標接收信號強度,以分貝表示
@property (readonly, nonatomic) NSInteger rssi;

// 7.反映信標相對距離的常數
typedef enum CLProximity : NSInteger {
	
	CLPriximityUnknown,
	CLProximityImmediate,
	CLProximityNear,
	CLProximityFar

} CLProximity;

指南針

1>CLHeading

包含 CLLocationManager 生成的標題數據.標題數據由真實值和磁北的計算值組成.它還包括用於計算這些值的三維向量的原始數據.

// 1.相對於磁北極的測量(度數)
// 此屬性中的值表示相對於磁極北極的標題,該磁極與地理北極不同。值0表示設備指向磁北極,90表示它指向東方,180表示它指向南方,等等。此屬性中的值應該總是有效的。
@property (readonly, nonatomic) CLLocationDirection magneticHeading;

// 2.與正北相對的標題(度)
@property (readonly, nonatomic) CLLocationDirection trueHeading;

// 3.報告的航向與真正的地磁航向最大的偏差
@property (readonly, nonatomic) CLLocationDirection headingAccuracy;

// 4.確定這個標題的時間
@property (readonly, nonatomic, copy) NSDate *timestamp;

// 5.x軸的地磁數據
// 此值表示由設備跟蹤的磁力線的 x 軸偏差
@property (readonly, nonatomic) CLHeadingComponentValue x;

// 6.y軸的地磁數據
@property (readonly, nonatomic) CLHeadingComponentValue y;

// 7.z軸的地磁數據
@property (readonly, nonatomic) CLHeadingComponentValue z;

// 8.車載硬件報告磁差的類型
typedef double CLHeadingComponentValue;

地理編碼

1>CLGeocoder

用於在地理坐標和地名之間轉換的單鏡頭對象

CLGeocoder 類提供了一種坐標轉換服務和一種用戶容易理解的(與用戶交互較好)坐標表示法.它通常由街道,城市,州和國家信息與給定位置相對應,但也可能含有相關的興趣點,地標或其他能識別的信息. CLGeocoder 對象是基於網絡服務來查看地標信息指定的坐標值.

使用地理編碼對象,創建和調用它的正向或反向地理編碼方法開始請求.

  • 反向地理編碼: 要求以經度和維度值,找到用戶可讀的地址.
  • 正向地理編碼: 要求以用戶可讀的地址,找到對應的經度和維度值.

應用程序應該注意它們如何使用地理編碼.每個 App 的地理編碼的請求速率是被限制的.因此,在短時間內發出太多請求,可能會導致一些請求失敗.(當超過最大速率的時候,地理編碼會返回一個 KCLErrorNetwork 錯誤對象的值給完成的回調).下面是一些有效使用這個類的經驗法則:

  • 對任何一個用戶行為發送不超過一個地理編碼的請求
  • 如果用戶執行多個動作,涉及地理編碼相同的位置.重用結果而不是去啟用每個動作的單個請求.
  • 當你希望自動更新用戶當前位置的時候,只有當用戶在一個合理的時間段內已經移動了一段距離的話才去發送一個新的地理編碼請求.舉個例子,在特殊的情況下,一分鍾不能發送超過一個請求.
  • 當用戶不能立即看到結果時,不要在一個時間開始編碼的請求.如不要開始編碼請求,當你的App在后台或者不活躍的時候

計算機或設備必須有訪問網絡的權限.以便能夠使地理編碼對象返回詳細的地標信息.地理編碼存儲足夠的本地化信息來報告本地化的國家名稱和許多地方的 ISO 國家代碼,如果某個特定的地點沒有國家的信息.地理編碼還會向你報告錯誤.

你可以使用地理編碼對象與 MapKit 框架結合着使用.也可以獨立使用.

[1] 反向地理編碼的位置
// 反向地理編碼一個指定的位置
// 該方法異步執行.完成請求的block塊在主線程執行.啟動反向地理編碼的請求后,不要嘗試啟動另一個反向或正向地理編碼的要求.
- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;
[2]地理編碼地址
// 1.根據指定的字典類型地址,完成地理編碼
- (void)geocodeAddressDictionary:(NSDictionary *)addressDictionary completionHandler:(CLGeocodeCompletionHandler)completionHandler;

// 2.根據指定的字符串類型地址,完成地理編碼
- (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;

// 3.根據指定的字符串類型地址和區域信息完成地理編碼
- (void)geocodeAddressString:(NSString *)addressString inRegion:(CLRegion *)region completionHandler:(CLGeocodeCompletionHandler)completionHandler;
[3]管理地理編碼的要求
// 1.取消掛起的地理編碼的要求
- (void)cancelGeocode;

// 2.指示進程是否正在地理編碼中
@property (nonatomic, readonly, getter=isGeocoding) BOOL geocoding;
[4]常量
// 地理編碼請求完成塊
// placemarks : 包含 CLPlacemark 對象數組.
typedef void (^CLGeocodeCompletionHandler)(NSArray<CLPlacemark *> *placemarks, NSError *error);

2>CLPlacemark

一個名稱 : 用戶很容易理解的描述方式.包含地點,地址和其他相關信息的名稱

由一個給定的維度和經度,CLPlacemark存儲了其對應的地標數據.其中信息有國家,州,市,街道地址等.它還可以包含興趣點和地理位置相關的數據.地標對象通常由一個 CLGeocoder 對象產生.

// 1.根據另一個地標返回一個地標對象
- (instancetype)initWithPlacemark:(CLPlacemark *)placemark;

// 2.根據指定的位置和地址信息創建並初始化一個地標對象
+ (instancetype)placemarkWithLocation:(CLLocation *)location name:(NSString *)name postalAddress:(CNPostalAddress *)postalAddress;

// 3.包含經緯度信息的位置對象
@property (nonatomic, readonly, copy) CLLocation *location;

// 4.地標名稱
@property (nonatomic, readonly, copy) NSString *name;

// 5.地址信息字典
@property(nonatomic, readonly, copy) NSDictionary *addressDictionary;

// 6.縮寫的國家名
@property(nonatomic, readonly, copy) NSString *ISOcountryCode;

// 7.與地標相關的國家名
@property(nonatomic, readonly, copy) NSString *country;

// 8.與地標相關的郵政編碼
@property(nonatomic, readonly, copy) NSString *postalCode;

// 9.國家或省相關的地標
@property(nonatomic, readonly, copy) NSString *administrativeArea;

// 10.其他行政區域的地標信息
@property(nonatomic, readonly, copy) NSString *subAdministrativeArea;

// 11.與地標相關的城市
@property(nonatomic, readonly, copy) NSString *locality

// 12.對於地標增設城市級信息
@property (nonatomic, readonly, copy) NSString *subLocality;

// 13.與地標相關街道地址
@property (nonatomic, readonly, copy) NSString *thoroughfare;

// 14.對於地標附加的街道信息
@property(nonatomic, readonly, copy) NSString *subThoroughfare;

// 15.與地標相關的地理區域
@property(nonatomic, readonly, copy) CLRegion *region;

// 16.與地標相關的時區
@property(nonatomic, readonly, copy) NSTimeZone *timeZone;

// 17.與地標相關的內陸水體名稱
@property(nonatomic, readonly, copy) NSString *inlandWater;

// 18.與地標相關的海洋名稱
@property(nonatomic, readonly, copy) NSString *ocean;

// 19.興趣與地標相關領域
@property(nonatomic, readonly, copy) NSArray<NSString *> *areasOfInterest;

錯誤

1>CLError

位置管理者對象返回的錯誤代碼

// 1.
typedef enum CLError : NSInteger {
    kCLErrorLocationUnknown = 0,
    kCLErrorDenied,
    kCLErrorNetwork,
    kCLErrorHeadingFailure,
    kCLErrorRegionMonitoringDenied,
    kCLErrorRegionMonitoringFailure,
    kCLErrorRegionMonitoringSetupDelayed,
    kCLErrorRegionMonitoringResponseDelayed,
    kCLErrorGeocodeFoundNoResult,
    kCLErrorGeocodeFoundPartialResult,
    kCLErrorGeocodeCanceled,
    kCLErrorDeferredFailed,
    kCLErrorDeferredNotUpdatingLocation,
    kCLErrorDeferredAccuracyTooLow,
    kCLErrorDeferredDistanceFiltered,
    kCLErrorDeferredCanceled,
    kCLErrorRangingUnavailable,
    kCLErrorRangingFailure
} CLError;


// 2.一個key, 對應的值是 CLRegion 對象
NSString *const KCLErrorUserInfoAlternateRegionKey;

// 3.核心位置錯誤的域
NSString *const KCLErrorDomain.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM