获取设备的地理位置和方向
一.概述
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.在确定应用程序的授权状态之前,启动位置服务是安全的.虽然可以启动位置服务,但这些服务不提供任何数据.直到授权状态变为KCLAuthorizationStatusAuthorizedAlways
或KCLAuthorizationStatusAuthorizedWhenInUse
.实现 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.如果程序未运行时发生区域越界.系统会自动将他唤醒.然后它可以处理事件.在这种情况下,为了表名您的应用程序时因为与位置相关的事件而启动的,将UIApplicationLaunchOptionsLocationKey
key传给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.