若看完这篇的朋友,可以查看我的下一篇iOS关于地图定位基础(二)
随着更多的LBS(Location Based Service)业务被集成到手机应用 同时鉴于在iOS中地图的学习是看了又忘,忘了又看,这次就干脆完完整整的写一篇关于iOS中地图的文章来供自己学习.大家如果觉得还行的话可以顶一下哦.
在iOS中若想实现地图定位大体的方案主要是 苹果原生 和 百度SDK 两种 . 接下来我们先开始讨论苹果原生的方案 . 在iOS中使用原生方案实现地图定位 , 必须依托两个自带框架CoreLocation<主要实现地理定位、地理编码、区域监听等功能性的实现> 和MapKit <地图展示,如大头针、路线、覆盖层等界面的展示>.
CoreLocation 的使用 ,首先需要创建CLLocationManager 对象 , 代码如下:
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
@interface ViewController () <CLLocationManagerDelegate> // 定位管理者协议
/**
* 定位管理者(避免局部变量销毁)
*/
@property (strong, nonatomic) CLLocationManager * clManager;
@end
@implementation ViewController
#pragma mark - lazy
- (CLLocationManager *)clManager {
if (!_clManager) {
_clManager = [[CLLocationManager alloc] init];
// 设置代理
_clManager.delegate = self;
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
// 代码获取用户授权(前台定位)
[_clManager requestWhenInUseAuthorization];
// 获取前后台定位 优先级大于前台定位
// [_clManager requestAlwaysAuthorization];
}
if ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0) {
// 代码允许后台定位(在代码授权为前台定位情况下,要实现后台定位)
_clManager.allowsBackgroundLocationUpdates = YES;
}
}
return _clManager;
}
然后我们调用CLLocationManager 的下面这个实例方法来开启定位
- (void)startUpdatingLocation;
但是奇迹发生了,运行程序后没有任何的效果(理论上手机界面会弹出是否允许使用定位的用户授权弹框),而且控制台也打印了些信息如下:
大体意思是,如果我们想要使用定位功能,就必须在项目的 Info.plist 文件中添加一个叫做 NSLocationAlwaysUsageDescription 或 NSLocationWhenInUseUsageDescription 的键值,而对应的value值是字符串类型,可以自定义一些授权弹框中的描述信息。如下图:
到目前为止,我们的应用就可以简单定位了,我们在弹出的授权弹框中选择允许,如下图:
并实现对应定位回调代理方法,发现代理方法不停的进行调用(不停的定位)
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
NSLog(@"已经获取定位~");
}
到此地图定位基础第一部分暂时写到这,下面总结一些相关的零碎知识点。
① 关于iOS8+的定位授权方法有两个,分别是
// 应用在前台时可以获取用户定位信息
- (void)requestWhenInUseAuthorization;
// 无论应用在前台或后台都能获取用户定位信息
- (void)requestAlwaysAuthorization;
// 但是两个方法如若都实现了,按照授权范围的包含和被包含关系,是以权限大的为基准,也就是以前后台定位授权方法为准。
② 在iOS8+中,代码授权若使用前台授权定位方法 ,在不改动代码情况下是否也能再实现后台定位呢?其实在工程项目中也可以进行相应设置实现。。。如下图(PS:同时如果我们的系统是iOS9+ 需要代码中设置允许后台定位的属性):
if ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0) {
// 代码允许后台定位(在代码授权为前台定位情况下,要实现后台定位)
_clManager.allowsBackgroundLocationUpdates = YES;
}
只不过当我们的应用退到后台时,屏幕顶部会有蓝色定位提醒框,如下图:
③ 关于用户的授权状态的监听 ( 这里定位管理者 CLLocationManager 也是通过代理的方式进行监听的)我们可以在代理方法中对状态参数status 进行分支判断 来查看当前授权状态 代理方法如下:
// 授权状态一旦改变 就会调用次代理方法
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
NSLog(@"授权状态发生改变!");
// CLAuthorizationStatus 授权状态 枚举类型
typedef NS_ENUM(int, CLAuthorizationStatus) {
// 用户还未决定是否授权 只有处在这种状态 应用才会弹出授权弹框
kCLAuthorizationStatusNotDetermined = 0,
// 定位权限受限
kCLAuthorizationStatusRestricted,
// 用户拒绝授权定位
kCLAuthorizationStatusDenied,
// 用户授权前后台都可定位
kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(10_12, 8_0),
// 用户授权前台定位
kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0),
}
}
④ 这里还有最后一个注意点 无论我们在手机上设置界面关闭定位服务还是拒绝授权定位 在授权状态代理方法中都是拒绝状态
// kCLAuthorizationStatusDenied 在确定是拒绝状态下 进一步判断
if ([CLLocationManager locationServicesEnabled]) {
NSLog(@"用户拒绝授权状态 - 提醒用户开启相应授权操作");
} else {
NSLog(@"用户关闭定位功能状态 - 提醒用户开启定位功能");
}
⑤ 下面附上用户手机设置页面对应的定位选项截图: