Cocoa框架-Core Location
来源:互联网 发布:淘宝店铺地址在哪里看 编辑:程序博客网 时间:2024/05/18 22:17
1. 简介
Core Location 是用于帮助设备确定当前的位置、运动朝向及基于位置的距离、速度、方向等信息的 iOS 框架。参考《精通iOS框架》做了简单的总结。
2. 使用步骤
应用显示位置经过下面几个简单的步骤:
(1)位置信息授权
1.首先,在应用中使用 Core Location 框架,需要导入 Core Location,使用指令:“import”:
@import CoreLocation;
2.然后在 .plist 文件中添加一个条目,用于说明程序将会使用用户位置信息。使用到2个相关的关键字:NSLocationWhenUseUsageDescription 或 NSLocationAlwaysUsageDescription 。若没有找到授权类型关键字,就不会调用该请求所允许的对话框。
Core Location 的访问服务策略有:
Always, While Using 或 Never 三种,分别对应的是允许访问设备的位置信息的三种类型。
- Always
表示即使在程序未激活时,用户也允许相应的程序访问位置信息。 - While Using
表示仅在应用处于前台且是激活状态时,允许访问设备的位置信息。 - Never
表示不允许访问设备的位置信息。
前面二者使用 CLLocationManager 类,调用的函数分别为:
//1. Always:requestAlwaysAuthorization//2. When in userequestWhenInUseAuthorization
- requestAlwaysAuthorization
按照苹果 API 的说法:
仅在必须后台启动位置服务时,才调用requestAlwaysAuthorization。按照苹果的隐私策略和用户对电池损耗的顾虑,必要情况下才使用此函数。 因为开启后,应用即使被手动关闭,在位置监控服务检测到位置变化等改变时,服务仍将重启。在应用处于后台时,iOS 将显示一个提示框,告知正在使用位置服务的 App 的信息。
*Calling this method will trigger a prompt to request “always”
* authorization from the user. If received, “always” authorization grants access to the user’s
* location via any CLLocationManager API, and grants access to
* launch-capable monitoring API such as geofencing/region monitoring,
* significante location visits, etc. Even if killed by the user, launch
* events triggered by monitored regions or visit patterns will cause a
* relaunch.
*
* “Always” authorization presents a significant risk to user privacy, and
* as such requesting it is discouraged unless background launch behavior
* is genuinely required. Do not call +requestAlwaysAuthorization unless
* you think users will thank you for doing so.
此图片来源于苹果官网,版权归苹果所有。
- requestWhenInUseAuthorization
“When in use” 类型的授权,从后台触发时,并不保证:激活位置,明显的地点变化和访问;startUpdatingLocation 函数也不会被触发。
“When-in-use” authorization does NOT enable monitoring API on regions,
* significant location changes, or visits, and -startUpdatingLocation will
* not succeed if invoked from the background.
调用位置服务后,应用在访问位置时,都会有弹框提示用户授权,如下图所示:
此弹框演示了开启位置授权的请求,来源于官网
当用户点击了弹框,将触发CLLocationManagerDelegate回调函数:
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_2);
通常的实现方式是:
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { // User has explicitly denied authorization for this application, or // location services are disabled in Settings. if (kCLAuthorizationStatusAuthorized == status) { //stop updating location NSString *errorMessage = @"Location Services Permission Denied"; NSDictionary *errorInfo = @{NSLocalizedDescriptionKey:errorMessage}; NSError *deniedError = [NSError errorWithDomain:@"ICFLocationErrorDomain" code:1 userInfo:errorInfo]; //handle error: show dialog for example. //now add log only. NSLog(@"location serviece was denied:%@",deniedError); } if (kCLAuthorizationStatusAuthorizedWhenInUse == status || kCLAuthorizationStatusAuthorizedAlways == status) { //start updating location }}
如果用户日后更改位置服务的权限,无论是更改单个应用还是更改整个设备的权限,都将触发同一个回调方法。
(2)检查服务
首先,检查设备是否开启了位置服务,可以使用 CLLocationManager 类中名为 locationServicesEnabled 的方法。
函数调用如下:
if ([CLLocationManager locationServicesEnabled]) { //handle location} else { // show information and // tell the user how to open location service}
在用户没权限处理有关服务的请求时,给予用户清楚的引导,使其能够顺利开启当前位置的服务功能。
(3)发起位置请求
在位置服务授权完成后, 就可以使用 CLLocationManager 实例获得当前位置。
在实际开发使用时,可以根据需要指定精确的参数,告诉 CLLocationManager 对象在目前电量使用情况下是否需要精确的定位,或者为了节省电量而选择较低精确度的定位,使用低精确度也可减少获取位置的时间。
设置距离过滤器可以让 CLLocationManager 对象知道在新位置生成前需要遍历多远的距离,可以基于位置变化进行微调。
最后,为 CLLocationManager 对象设置委托,对于位置事件和权限情况的改变等,可以回调处理。当应用准备获取位置时,会请求位置管理器对象更新位置。
CLLocationManager *manager = [[CLLocationManager alloc] init];[manager setDesiredAccuracy:kCLLocationAccuracyBest];[manager setDistanceFilter:100.0f];[manager setDelegate:self];
可选的位置精度信息如下:
/* * kCLLocationAccuracy<x> * * Discussion: * Used to specify the accuracy level desired. The location service will try its best to achieve * your desired accuracy. However, it is not guaranteed. To optimize * power performance, be sure to specify an appropriate accuracy for your usage scenario (eg, * use a large accuracy value when only a coarse location is needed). */extern const CLLocationAccuracy kCLLocationAccuracyBestForNavigation __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_0);extern const CLLocationAccuracy kCLLocationAccuracyBest;extern const CLLocationAccuracy kCLLocationAccuracyNearestTenMeters;extern const CLLocationAccuracy kCLLocationAccuracyHundredMeters;extern const CLLocationAccuracy kCLLocationAccuracyKilometer;extern const CLLocationAccuracy kCLLocationAccuracyThreeKilometers;
位置的更新参数可选,当达到指定的更新参数值时,位置将更新:
/* * distanceFilter * * Discussion: * Specifies the minimum update distance in meters. Client will not be notified of movements of less * than the stated value, unless the accuracy has improved. Pass in kCLDistanceFilterNone to be * notified of all movements. By default, kCLDistanceFilterNone is used. */@property(assign, nonatomic) CLLocationDistance distanceFilter;
根据参数设置情况, CLLocationManager 将选择 GPS 或 Wi-Fi, 或者同时使用这两者来确定位置。当位置管理器更新当前位置或无法更新当前位置时,需要实现这两个委托方法。
- 成功当成功获得位置信息时,会调用 locationManager:didUpdateLocations: 方法。
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations { // Get last location CLLocation *lastLocation = [locations lastObject]; if (0 > lastLocation.horizontalAccuracy) { return; } //use lastLocation}
位置传感器可以传递数组包含的多个位置信息,数组中的最后一个对象就是最近刷新的位置,位置管理器还可以在实际获取位置前快速返回最后一次 GPS 的位置信息,不过这样的话,如果 GPS 关闭并且设备此时发生位移,位置就会出错。
位置管理器会随着位置的刷新多次调用该方法,所以这里的任何逻辑处理都要注意到这一点。
- 失败
当没有获取位置信息时,将调用
locationManager:didFailWithError: 方法。
出错的可能包括:GPS 或 Wi-Fi 不可用,位置服务被关闭等。程序会通知位置管理器更新位置信息,并捕捉位置信息用来显示。
需要补充的是:位置管理器可以对位置变化进行过滤,以拒绝对微小的变化进行处理。
CLLocationDegrees degreesFilter = 2.0;if ([CLLocationManager headingAvailable]) { [manager setHeadingFilter:degreesFilter]; [manager startUpdatingHeading];}
运动朝向事件会通过委托:
locationManager:didUpdateHeading:
进行回调处理。
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(nonnull CLHeading *)newHeading { NSLog(@"New heading, magnetic:%f",newHeading.magneticHeading); NSLog(@"New heading, true:%f",newHeading.trueHeading); NSLog(@"Accuracy:%f",newHeading.headingAccuracy); NSLog(@"Timestamp:%@",newHeading.timestamp);}
新的运动朝向包括:磁极和真实朝向,从正北方向按度的单位来表示;其提供一种正确的读法,用数字表示磁场方向的度数:正值表示更精确的朝向,负值表示朝向无效,或者存在磁场干扰无法读数。
时间戳信息会记录读数发生的时间,以避免使用之前未更新的朝向信息。
(4)解析使用
当位置管理器返回信息时,就会生成一个 CLLocation 实例。 CLLocation 实例包含许多位置相关的信息:
- CLLocationCoordinate2D
2维位置信息,包括经纬度。
其中纬度使用赤道以北或以南的值表示,北纬为正值,北极为90度;南纬为负值,南极为-90度;
经度则以本初子午线为准,向西为负,最大到 -180度,向东为正,最大值为180度。
如果设备具有 GPS 功能,那么位置信息还会包含垂直精度信息。 - CLLocationAccuracy
单位为米,表示距坐标指定的范围多少米的距离。
具有horizontalAccuracy(水平精度)和 verticalAccuracy (垂直精度)两个值。 - CLLocationDistance
返回精度为米的距离值。 - CLLocationSpeed
返回以米/秒的速度信息 - CLLocationDirection
返回以正北计算表示的路径信息
(5)重大变更通知
在设备发生较大位移时通知应用,这样可以很好地维持 GPS 和 Wi-Fi 检测当前位置,又能有效节省设备的电量。
[manager startMonitoringSignificantLocationChanges];
异步调用返回时,会调用delegate的回调:
locationManager:didUpdateLocations:
位移超过500米或者换基站时会产生一条通知,上一次通知过去 5 分钟内不会重复发送通知。
3. 总结
Core Location 通过设置位置服务请求类型、编辑plist文件来开启位置服务,发起位置请求,回调解析位置信息,并在位置发生改变时更新。
位置信息包括经纬度、速度、朝向和距离变化值等信息,通过委托模式,在位置发生改变时更新上述位置信息。
- Cocoa框架-Core Location
- ios-Core Location框架
- Core Location框架基本概念理解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- [Cocoa]深入浅出 Cocoa 之 Core Data(1)- 框架详解
- 单个舵机串口控制
- 核心驱动力——所有权与拥有感
- luogu P1064 金明的预算方案
- 社交影响与关联性——使用技巧
- UIView设置圆角、边框和阴影
- Cocoa框架-Core Location
- 你不知道的颠覆式创新者
- 博弈模板
- 稀缺性与渴望——使用技巧
- 基于jdk和cglib实现的动态代理
- 未知性与好奇心——使用技巧
- 动态规划入门(五)
- Android 6 camera.open()异常解决方法
- 520. Detect Capital