1.iOS8以前使用CLLocationManager
- 1.导入头文件
<CoreLocation/CoreLocation.h>
- 2.创建位置管理者
CLLocationManager
, 并添加到属性。 - 3.设置代理、遵守协议、实现代理方法,在代理方法中获取位置信息
- 4.调用开始更新位置方法
-
5.设置
每隔多远定位一次
和精确度
,精确度越高越耗电,定位时间越长// 1.设置位置管理者属性 @property (nonatomic, strong) CLLocationManager *lcManager; // 2.判断是否打开了位置服务 if ([CLLocationManager locationServicesEnabled]) { // 创建位置管理者对象 self.lcManager = [[CLLocationManager alloc] init]; self.lcManager.delegate = self; // 设置代理 // 设置定位距离过滤参数 (当本次定位和上次定位之间的距离大于或等于这个值时,调用代理方法) self.lcManager.distanceFilter = 100; self.lcManager.desiredAccuracy = kCLLocationAccuracyBest; // 设置定位精度(精度越高越耗电) [self.lcManager startUpdatingLocation]; // 开始更新位置 } /** 获取到新的位置信息时调用*/ -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { NSLog(@"定位到了"); } /** 不能获取位置信息时调用*/ -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog(@"获取定位失败"); }
- 6.请求授权,iOS6之后,苹果开始加强保护用户隐私,在
Info.plist
文件中定义Key
提醒用户,提高用户允许定位的概率。
Info.plist 设置Key - 7.如果要后台定位,需要打开后台模式
勾选后台模式
2.iOS8.0之后使用CLLocationManager
- 1.iOS8之后,苹果又进一步加强了隐私保护,不会主动填出对话框,让用户选择
- 2.需要实现两个方法(实现其一即可),并且
Info.plist
中设置对应的key
,才会弹框
1.requestWhenInUseAuthorization
- 1.当程序当前的授权状态为未决定时,在前台时请求定位服务许可时使用。需要先在 Info.plist 文件中设置一个Key:
NSLocationWhenInUseUsageDescription
, 如果不设置key,系统会忽略定位请求。
Info.plist 设置对应的Key -
2.当用户授权
when-in-use
时,程序在前台时可以启动大部分定位服务。如果想要后台定位,需要开启后台定位模式,但在状态栏会出现蓝条提示用户程序正在进行定位。[_lcManager requestWhenInUseAuthorization];
请求定位的弹框

后台模式下的 blue bar
2.requestAlwaysAuthorization
- 1.请求前后台定位服务授权,当授权状态为未决定时请求用户授权。前提是在
Info.plist
文件中包含keyNSLocationAlwaysUsageDescription

Info.plist中 设置对应的Key

请求定位的弹框
3.注意
- 1.iOS8之后,如果想要定位,必须调用
requestWhenInUseAuthorization
或requestAlwaysAuthorization
方法。 - 2.如果两个请求授权的方法都执行了,会出现以下情况
- 1.
when-in-use
写在前面,第一次打开程序时请求授权,如果勾选了后台模式,进入后台会出现蓝条提示正在定位。当程序退出,第二次打开程序时Always
会再次请求授权。之后进入后台就不会出现蓝条了(前后台都能定位)。 - 2.
Always
写在前面,when-in-use
写在后面,只会在第一次打开程序时请求授权,因为Always
得到的授权大于when-in-use
的到的授权
- 1.
4.判断是否开启了定位服务
- 在启动更新位置之前要先判断是否开启了定位服务
if ([CLLocationManager locationServicesEnabled]) { // 判断是否打开了位置服务 [self.lcManager startUpdatingLocation]; // 开始更新位置 }
5.适配版本号的方法
when-in-use
和Always
都是iOS8之后出现的方法,如果不进行版本适配,运行在iOS7上就会crash,此时需要做版本号判断- 1.判断版本号
if ([[UIDevice currentDevice].systemVersion floatValue] >=8.0 ) { [_lcManager requestAlwaysAuthorization]; }
- 2.适配版本的另一种方法
if ([_lcManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { [_lcManager requestWhenInUseAuthorization]; }
6.监听定位服务状态的改变
- 实现代理方法,判断定位服务的状态
/** 定位服务状态改变时调用*/ -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { switch (status) { case kCLAuthorizationStatusNotDetermined: { NSLog(@"用户还未决定授权"); break; } case kCLAuthorizationStatusRestricted: { NSLog(@"访问受限"); break; } case kCLAuthorizationStatusDenied: { // 类方法,判断是否开启定位服务 if ([CLLocationManager locationServicesEnabled]) { NSLog(@"定位服务开启,被拒绝"); } else { NSLog(@"定位服务关闭,不可用"); } break; } case kCLAuthorizationStatusAuthorizedAlways: { NSLog(@"获得前后台授权"); break; } case kCLAuthorizationStatusAuthorizedWhenInUse: { NSLog(@"获得前台授权"); break; } default: break; } }
7.代理方法返回的 locations
信息
- 当位置管理器,获取到位置后,调用
locationManager:didUpdateLocations:
方法,返回的类型为CLLocation
的位置信息数组,以下为数组包含的属性- 1.coordinate : 当前位置的坐标
- latitude : 纬度
- longitude : 经度
- 2.altitude : 海拔,高度
- 3.horizontalAccuracy : 纬度和经度的精度
- 4.verticalAccuracy : 垂直精度(获取不到海拔时为负数)
- 5.course : 行进方向(真北)
- 6.speed : 以米/秒为单位的速度
- 7.description : 位置描述信息
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { CLLocation *location = [locations firstObject]; NSLog(@"%@", location); }
- 1.coordinate : 当前位置的坐标
3.iOS9.0之后使用CLLocationManager
- 1.iOS9.0之后有一种新的请求定位的方法
requestLocation
- 2.作用:按照定位精确度从低到高进行排序,逐个进行定位。如果获取到的位置不是精确度最高的那个,也会在定位超时后,通过代理告诉外界。
- 3.注意:
- 1.必须实现
ocationManager:didUpdateLocations:
和locationManager:didFailWithError
方法,但是只调用一次 - 2.不能与
startUpdatingLocation
同时使用if ([CLLocationManager locationServicesEnabled]) { // 判断是否打开了位置服务 [self.lcManager requestLocation]; }
- 1.必须实现
-
4.实现
requestWhenInUseAuthorization
或requestAlwaysAuthorization
方法,并设置对应的 keyif ([[UIDevice currentDevice].systemVersion floatValue] >=8.0 ) { // iOS0.0:如果当前的授权状态是使用是授权,那么App退到后台后,将不能获取用户位置,即使勾选后台模式:location [_lcManager requestWhenInUseAuthorization]; }
-
5.必须勾选后台模式,并设置
allowsBackgroundLocationUpdates
属性为YES(默认是NO)- 1.当定位完成时,设置为NO,并且不再定位跟踪
-
2.使用
-responsdToSelector:
判断// iOS9.0+ 要想继续获取位置,需要使用以下属性进行设置(注意勾选后台模式:location)但会出现蓝条 if ([_lcManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)]) { _lcManager.allowsBackgroundLocationUpdates = YES; }