iOS開發之CoreLocation框架使用

iOS開發之CoreLocation框架使用

     CoreLocation框架是iOS開發中比較基礎的一個位置信息相關框架,關於定位和地圖,以前也有博客多詳細的介紹。可是對於CoreLocation框架,並無完整和細緻的記錄。本篇博客將剖析這個框架的結構並進行應用示例。下圖爲CoreLocation框架的相關類佈局圖:git

從圖中能夠看到,在CoreLocation框架中除了一些數據模型,CLLocationManager做用最爲重要,它是整個框架的管理中心,從圖中也能夠看出,CoreLocation框架功能也很是完善,常規定位,方向信息獲取,室內定位,GEO編碼等功能都支持。數組

1、CLLocationManager管理類詳解

CLLocationManager做爲整個CoreLocation框架的核心管理類,其第一部分功能是獲取設備的功能可用性,以下:框架

//獲取位置服務是否可用
+ (BOOL)locationServicesEnabled;
//獲取方向信息服務是否可用
+ (BOOL)headingAvailable;
//獲取設備是否支持顯著位置更改的監聽
+ (BOOL)significantLocationChangeMonitoringAvailable;
//獲取是否支持針對某種位置區域改變的監聽
+ (BOOL)isMonitoringAvailableForClass:(Class)regionClass;
//獲取是否支持區域監聽 同上面一個函數做用一致
+ (BOOL)regionMonitoringAvailable;
//獲取區域監聽是否可用 除了設備支持 還須要 用戶受權
+ (BOOL)regionMonitoringEnabled;
//獲取是否支持測距
+ (BOOL)isRangingAvailable;

在使用CLLocationManager的服務以前,首先須要獲取用戶的受權,在iOS8以後,還須要在info.plist中添加相關的鍵,以下:ide

上面標出的3個鍵,只須要設置一個,根據本身的定位要求來選擇便可。函數

下面列出了與用戶受權相關的方法:工具

//獲取當前用戶受權類型
/*
CLAuthorizationStatus枚舉以下:
kCLAuthorizationStatusNotDetermined  用戶目前尚未選擇
kCLAuthorizationStatusRestricted     當前應用還沒有受權
kCLAuthorizationStatusDenied         用戶拒絕使用位置服務
kCLAuthorizationStatusAuthorizedAlways 用戶受權始終可使用位置服務
kCLAuthorizationStatusAuthorizedWhenInUse 用戶受權能夠在APP使用時使用位置
kCLAuthorizationStatusAuthorized      用戶受權使用位置  iOS8以前
*/
+ (CLAuthorizationStatus)authorizationStatus;
//請求在APP使用時使用用戶的位置信息
- (void)requestWhenInUseAuthorization;
//請求始終使用用戶的位置信息
- (void)requestAlwaysAuthorization;

下面列舉了CLLocationManager中核心的屬性和方法:佈局

//設置代理
@property(assign, nonatomic, nullable) id<CLLocationManagerDelegate> delegate;
//定位服務是否可用
@property(readonly, nonatomic) BOOL locationServicesEnabled;
//位置服務的用途,目前這個屬性再也不使用,在info.plist中配置
@property(copy, nonatomic, nullable) NSString *purpose;
//指定定位活動的行爲
/*
CLActivityTypeAutomotiveNavigation 汽車導航
CLActivityTypeFitness    步行
CLActivityTypeOtherNavigation  其餘導航 如火車 輪船
CLActivityTypeAirborne  飛機導航
CLActivityTypeOther 其餘類型

*/
@property(assign, nonatomic) CLActivityType activityType;
//設置以米爲單位的精度,當小於此精度的位置改變不會收到通知CLLocationDistance就是double類型
@property(assign, nonatomic) CLLocationDistance distanceFilter;
//設置預期的定位精度CLLocationAccuracy爲double類型 不必定徹底精準 只是設置預期
@property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;
//設置是否自動暫停位置更新 根據電量等
@property(assign, nonatomic) BOOL pausesLocationUpdatesAutomatically;
//設置是否在後臺一直更新定位
@property(assign, nonatomic) BOOL allowsBackgroundLocationUpdates;
//當後臺定位時 是否顯示活動指示器 在狀態欄上
@property(assign, nonatomic) BOOL showsBackgroundLocationIndicator;
//最近的一次位置信息
@property(readonly, nonatomic, copy, nullable) CLLocation *location;
//是否支持方向
@property(readonly, nonatomic) BOOL headingAvailable;
//設置最小方向更新精度
@property(assign, nonatomic) CLLocationDegrees headingFilter;
//用來做爲參考的物理設備方向
/*
    CLDeviceOrientationUnknown ,
	CLDeviceOrientationPortrait,
	CLDeviceOrientationPortraitUpsideDown,
	CLDeviceOrientationLandscapeLeft,
	CLDeviceOrientationLandscapeRight,
	CLDeviceOrientationFaceUp,
	CLDeviceOrientationFaceDown
*/
@property(assign, nonatomic) CLDeviceOrientation headingOrientation;
//最近一次更新的方向信息
@property(readonly, nonatomic, copy, nullable) CLHeading *heading;
//設置最大的區域監聽範圍
@property (readonly, nonatomic) CLLocationDistance maximumRegionMonitoringDistance;
//一組目前正在監聽的範圍集合
@property (readonly, nonatomic, copy) NSSet<__kindof CLRegion *> *monitoredRegions;
//返回一組支持測距的範圍
@property (readonly, nonatomic, copy) NSSet<__kindof CLRegion *> *rangedRegions;
//開始更新位置信息
- (void)startUpdatingLocation;
//中止更新位置信息
- (void)stopUpdatingLocation;
//請求一次位置信息
- (void)requestLocation;
//開始更新方向信息
- (void)startUpdatingHeading;
//中止更新方向信息
- (void)stopUpdatingHeading;
//取消航向校準
- (void)dismissHeadingCalibrationDisplay;
//開始顯著位置變化的監聽
- (void)startMonitoringSignificantLocationChanges;
//中止線束位置變化的監聽
- (void)stopMonitoringSignificantLocationChanges;
//開啓範圍監聽
- (void)startMonitoringForRegion:(CLRegion *)region
                 desiredAccuracy:(CLLocationAccuracy)accuracy;
- (void)startMonitoringForRegion:(CLRegion *)region;
//中止範圍監聽
- (void)stopMonitoringForRegion:(CLRegion *)region;
//獲取指定區域的狀態 會在代理回調中返回
- (void)requestStateForRegion:(CLRegion *)region;
//開始計算信標範圍  關於Beacon 是一種專門的室內定位服務
- (void)startRangingBeaconsInRegion:(CLBeaconRegion *)region;
//中止計算信標範圍
- (void)stopRangingBeaconsInRegion:(CLBeaconRegion *)region;
//容許延遲更新  即位置改變了多少距離或者間隔了多少秒後更新
- (void)allowDeferredLocationUpdatesUntilTraveled:(CLLocationDistance)distance
					  timeout:(NSTimeInterval)timeout;
//不容許進行延遲更新
- (void)disallowDeferredLocationUpdates;
//設備是否支持延遲更新
+ (BOOL)deferredLocationUpdatesAvailable;

2、CLLocationManagerDelegate協議

        CLLocationManagerDelegate配合CLLocationManager進行使用,其中定義了管理器在提供服務時進行回調的相關函數。解析以下:post

//位置更新後調用的回調 會將原位置和更新後的位置信息傳入
- (void)locationManager:(CLLocationManager *)manager
	didUpdateToLocation:(CLLocation *)newLocation
		   fromLocation:(CLLocation *)oldLocation;
//位置更新後調用的回調 會傳入按時間排序的一組位置信息對象
- (void)locationManager:(CLLocationManager *)manager
	 didUpdateLocations:(NSArray<CLLocation *> *)locations;
//方向信息更新後調用的回調
- (void)locationManager:(CLLocationManager *)manager
       didUpdateHeading:(CLHeading *)newHeading;
//返回布爾值設置是否須要進行方向校準
- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager;
//當監聽的區域狀態變化時調用
/*
CLRegionState定義區域的狀態
CLRegionStateUnknown 未知狀態
CLRegionStateInside  進入
CLRegionStateOutside 出去
*/
- (void)locationManager:(CLLocationManager *)manager
	didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region ;
//區域內有新的信標可用時調用
- (void)locationManager:(CLLocationManager *)manager
	didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region;
//區域內的信標測距發生錯誤時調用
- (void)locationManager:(CLLocationManager *)manager
	rangingBeaconsDidFailForRegion:(CLBeaconRegion *)region
	withError:(NSError *)error;
//進入監聽區域時調用
- (void)locationManager:(CLLocationManager *)manager
	didEnterRegion:(CLRegion *)region;
//退出監聽區域時調用
- (void)locationManager:(CLLocationManager *)manager
	didExitRegion:(CLRegion *)region;
//服務發生錯誤時調用
- (void)locationManager:(CLLocationManager *)manager
	didFailWithError:(NSError *)error;
//監聽區域發生錯誤時調用
- (void)locationManager:(CLLocationManager *)manager
	monitoringDidFailForRegion:(nullable CLRegion *)region
	withError:(NSError *)error;
//用戶受權改變時調用
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status;
//開啓區域監聽時調用
- (void)locationManager:(CLLocationManager *)manager
	didStartMonitoringForRegion:(CLRegion *)region;
//暫停位置更新時調用
- (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager;
//恢復位置更新時調用
- (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager;
//延遲更新位置信息錯誤時調用
- (void)locationManager:(CLLocationManager *)manager
	didFinishDeferredUpdatesWithError:(nullable NSError *)error;
//若是啓用了訪問監聽 則收到訪問會調用
- (void)locationManager:(CLLocationManager *)manager didVisit:(CLVisit *)visit;

3、進行GEO編碼的工具類CLGeocoder

      如前所述,使用CLLocationManager獲取到的位置信息是CLLocation對象,這個對象封裝了經緯度等基礎信息,可是在實際開發中,咱們每每須要獲取到的是位置的更多實際信息,好比國家,省份,城市等等,GEO編碼的做用就是經過經緯度信息發起請求,獲取現實意義的更多數據。CLGeocoder類解析以下:編碼

//是否正在進行GEO編碼
@property (nonatomic, readonly, getter=isGeocoding) BOOL geocoding;
//反地理位置信息編碼 
/*
CLGeocodeCompletionHandler會傳回一組標誌建築物
*/
- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;
//做用同上 local用來設置區域 能夠經過這個參數控制返回的語言
- (void)reverseGeocodeLocation:(CLLocation *)location preferredLocale:(nullable NSLocale *)locale completionHandler:(CLGeocodeCompletionHandler)completionHandler;

//下面這些方法一般與 AddressBook配合使用
//將地址信息字典進行編碼 這個方法與AddressBook框架配合使用 AddressBook框架中定義這個字典
- (void)geocodeAddressDictionary:(NSDictionary *)addressDictionary completionHandler:(CLGeocodeCompletionHandler)completionHandler;
- (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;
- (void)geocodeAddressString:(NSString *)addressString inRegion:(nullable CLRegion *)region completionHandler:(CLGeocodeCompletionHandler)completionHandler;
- (void)geocodeAddressString:(NSString *)addressString inRegion:(nullable CLRegion *)region preferredLocale:(nullable NSLocale *)locale completionHandler:(CLGeocodeCompletionHandler)completionHandler;
//對郵編地址進行GEO編碼
- (void)geocodePostalAddress:(CNPostalAddress *)postalAddress completionHandler:(CLGeocodeCompletionHandler)completionHandler;
- (void)geocodePostalAddress:(CNPostalAddress *)postalAddress preferredLocale:(nullable NSLocale *)locale completionHandler:(CLGeocodeCompletionHandler)completionHandler;
//取消編碼
- (void)cancelGeocode;

4、位置信息模型CLLocation相關類

    首先在CoreLocation框架中,位置的經緯度是由CLLocationCoordinate2D結構體描述的,這個結構體定義以下:atom

struct CLLocationCoordinate2D {
	CLLocationDegrees latitude; //精度
	CLLocationDegrees longitude;//維度
};

使用下面的函數能夠快速的檢查和建立CLLocationCoordinate2D對象:

//檢查經緯度對象是否有效
BOOL CLLocationCoordinate2DIsValid(CLLocationCoordinate2D coord);
//建立對象
CLLocationCoordinate2D CLLocationCoordinate2DMake(CLLocationDegrees latitude, CLLocationDegrees longitude);

CLFloor類是一個用來描述樓層信息的模型,並不必定精準,是基於地面的粗略計算,其中屬性以下:

@interface CLFloor : NSObject <NSCopying, NSSecureCoding>
//樓層 地下室可能爲負值
@property(readonly, nonatomic) NSInteger level;

@end

下面列舉了CLLocation中封裝的屬性的方法:

//初始化方法
//經過經緯度初始化 CLLocationDegrees就是double類型
- (instancetype)initWithLatitude:(CLLocationDegrees)latitude
	longitude:(CLLocationDegrees)longitude;
//初始化方法
/*
hAccuracy設置水平方向的精確度
verticalAccuracy 設置垂直方向的精確度
timestamp 設置時間戳
*/
- (instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate
	altitude:(CLLocationDistance)altitude
	horizontalAccuracy:(CLLocationAccuracy)hAccuracy
	verticalAccuracy:(CLLocationAccuracy)vAccuracy
	timestamp:(NSDate *)timestamp;
/*
course設置方向
speed 設置速度
*/
- (instancetype)initWithCoordinate:(CLLocationCoordinate2D)coordinate
    altitude:(CLLocationDistance)altitude
    horizontalAccuracy:(CLLocationAccuracy)hAccuracy
    verticalAccuracy:(CLLocationAccuracy)vAccuracy
    course:(CLLocationDirection)course
    speed:(CLLocationSpeed)speed
    timestamp:(NSDate *)timestamp;
//獲取位置對象的經緯度信息
@property(readonly, nonatomic) CLLocationCoordinate2D coordinate;
//獲取海波高度
@property(readonly, nonatomic) CLLocationDistance altitude;
//水平方向精度
@property(readonly, nonatomic) CLLocationAccuracy horizontalAccuracy;
//垂直方向精度
@property(readonly, nonatomic) CLLocationAccuracy verticalAccuracy;
//方向值 0-360之間
@property(readonly, nonatomic) CLLocationDirection course;
//速度  單位m/s
@property(readonly, nonatomic) CLLocationSpeed speed;
//時間戳
@property(readonly, nonatomic, copy) NSDate *timestamp;
//樓層信息
@property(readonly, nonatomic, copy, nullable) CLFloor *floor;
//獲取到某個位置之間的距離
- (CLLocationDistance)getDistanceFrom:(const CLLocation *)location;
- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location;

5、航向信息模型CLHeading

      當使用CLLocationManager進行航向信息的請求時,代理回調中會獲取到CLHeading對象,這個對象封裝了航向相關數據,解析以下:

//地磁方向0-360
@property(readonly, nonatomic) CLLocationDirection magneticHeading;
//地理方向0-360
@property(readonly, nonatomic) CLLocationDirection trueHeading;
//航向精度
@property(readonly, nonatomic) CLLocationDirection headingAccuracy;
//x軸測量的原始值
@property(readonly, nonatomic) CLHeadingComponentValue x;
//y軸測量的原始值
@property(readonly, nonatomic) CLHeadingComponentValue y;
//z軸測量的原始值
@property(readonly, nonatomic) CLHeadingComponentValue z;
//時間戳
@property(readonly, nonatomic, copy) NSDate *timestamp;

6、地標數據模型CLPlacemark

    CLPlacemark是進行GEO編碼後返回的地標對象,解析以下:

//初始化方法 使用另外一個placemark拷貝
- (instancetype)initWithPlacemark:(CLPlacemark *) placemark;
//位置信息
@property (nonatomic, readonly, copy, nullable) CLLocation *location;
//區域範圍信息
@property (nonatomic, readonly, copy, nullable) CLRegion *region;
//時區
@property (nonatomic, readonly, copy, nullable) NSTimeZone *timeZone;
//地理信息字典
@property (nonatomic, readonly, copy, nullable) NSDictionary *addressDictionary;
//地標名字
@property (nonatomic, readonly, copy, nullable) NSString *name;
//街道名字
@property (nonatomic, readonly, copy, nullable) NSString *thoroughfare;
//子街道名字
@property (nonatomic, readonly, copy, nullable) NSString *subThoroughfare;
//城鎮
@property (nonatomic, readonly, copy, nullable) NSString *locality;
//子城鎮
@property (nonatomic, readonly, copy, nullable) NSString *subLocality;
//州域信息
@property (nonatomic, readonly, copy, nullable) NSString *administrativeArea;
//子州域信息
@property (nonatomic, readonly, copy, nullable) NSString *subAdministrativeArea;
//郵編
@property (nonatomic, readonly, copy, nullable) NSString *postalCode;
//ISO國家編碼
@property (nonatomic, readonly, copy, nullable) NSString *ISOcountryCode;
//國家
@property (nonatomic, readonly, copy, nullable) NSString *country;
//水域名稱
@property (nonatomic, readonly, copy, nullable) NSString *inlandWater;
//海洋名稱
@property (nonatomic, readonly, copy, nullable) NSString *ocean;
//相關的興趣點數組
@property (nonatomic, readonly, copy, nullable) NSArray<NSString *> *areasOfInterest;

在CLPlacemark對象中有封裝region對象,這個對象封裝區域信息,以下:

//經過中心點和半徑建立區域
- (instancetype)initCircularRegionWithCenter:(CLLocationCoordinate2D)center
									  radius:(CLLocationDistance)radius
								  identifier:(NSString *)identifier;
//區域中心
@property (readonly, nonatomic) CLLocationCoordinate2D center;
//半徑
@property (readonly, nonatomic) CLLocationDistance radius;
//進入區域是否發出提醒  須要開啓了位置區域監聽
@property (nonatomic, assign) BOOL notifyOnEntry;
//離開區域是否發出提醒  須要開啓了位置區域監聽
@property (nonatomic, assign) BOOL notifyOnExit;
//檢查某個點是否在區域內
- (BOOL)containsCoordinate:(CLLocationCoordinate2D)coordinate;

CLRegion類還有兩個子類,CLCircularRegion類用來建立圓形區域,提供了一個便捷的初始化方法,其做用和CLRegion基本一致。CLBeaconRegion專門用來支持Beacon技術,Beacon技術是室內定位技術的一種,例如商場中有不少店鋪,若是有店鋪部署了Beacon發射設備,則當iOS設備做爲接收設備靠近時會受到通知。CLBeaconRegion除了包含基礎的區域信息外,還封裝了與Beacon設備相關的設備碼等信息。

7、區域訪問功能

    在iOS8以前,若是咱們想獲取用戶是否在某個區域停留了一段時間是比較困難的,可能要屢次定位並進行整理和分析。在iOS8後,CoreLocation框架中提供了方便的方法來處理這個問題。

    首先,用戶的區域停留能夠理解爲用戶對某個區域進行了訪問,開啓和關閉訪問監聽十分方便,以下:

@interface CLLocationManager (CLVisitExtensions)
//開啓服務
- (void)startMonitoringVisits;
//關閉服務
- (void)stopMonitoringVisits;
@end

開啓後,當有相關的訪問信息時,會回調代理中的相應函數,而且收到CLVisit對象,這個對象信息以下:

//訪問開始時間
@property (nonatomic, readonly, copy) NSDate *arrivalDate;
//訪問結束時間
@property (nonatomic, readonly, copy) NSDate *departureDate;
//位置
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
//精度
@property (nonatomic, readonly) CLLocationAccuracy horizontalAccuracy;

熱愛技術,熱愛生活,寫代碼,交朋友 琿少  QQ:316045346

相關文章
相關標籤/搜索