需要导入
补充说明,导入头文件后,系统会自动帮助导入CoreLocation框架
操作步骤:
1.创建管理者(CLLocationManager)
2.请求授权 (request) 需要设置info.plist
3.设置代理,获取数据(需要强引用)
4.开始定位 (startUpdatingLocation)
5.didUpdateLocations代理方法
1).底层获取数据在子线程,使用时在主线程,苹果自动帮助开发者做了线程管理
2).存在延迟,所以位置管理者需要强引用
3).该方法会持续的返回位置信息,无论位置是否发生改变,停止定位:stopUpdatingLocation
- 创建位置管理者 统一管理位置服务(manager设置强引用)
//位置管理者
@property (nonatomic, strong) CLLocationManager *mgr;
self.manager = [[CLLocationManager alloc] init];
- 请求授权
1).WhenInUseAuthorization (前台)
2).AlwaysAuthorization (前后台都可以)
3).后台模式/前台+临时后台(配合NSLocationWhenInUseUsageDescription使用)
还需要设置info.plist 添加
NSLocationWhenInUseUsageDescription 使用时
NSLocationAlwaysUsageDescription 前后台
//requestWhenInUseAuthorization是 IOS 8.0开始支持,如果兼容低版本,先判断能否响应requestWhenInUseAuthorization方法
if ([self.manager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.manager requestWhenInUseAuthorization];
}
前台:
始终(前后台):
临时后台:开启临时后台设置:
IOS 9以后 后台或临时后台除了要设置info.plist文件外
都还需要代码允许后台模式,这样的好处是将不同的需求分离开,可以更省电(不同的位置管理者分开设置是否允许后台)
始终:NSLocationAlwaysUsageDescription
临时:NSLocationWhenInUseUsageDescription
self.manager.allowsBackgroundLocationUpdates = YES;
- 获取数据 设置代理 遵循协议 实现代理方法
@interface ViewController ()
self.manager.delegate = self;
/**
* 当已经获取定位信息后调用,该方法会持续返回位置信息(无论位置是否发生变化)
*
* @param manager 位置管理者
* @param locations 数组<位置对象>
*/
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
//CLLocation 位置对象
CLLocation *location = locations.lastObject;
//打印坐标(经纬度)
NSLog(@"%f, %f", location.coordinate.latitude, location.coordinate.longitude);
//[manager stopUpdatingLocation];停止定位(一次性定位)
}
- 开始定位
[self.manager startUpdatingLocation];
- 定位操作耗时耗电,位置不改变的时候不需要持续定位,位置改变再开启定位,所以还需要优化持续化定位
距离筛选器 (distanceFilter) 减少不必要的代理回调
// 距离筛选器(单位: 米) 当距离没有超出设定范围内,就不会有回调
self.manager.distanceFilter = 100;
期望精确度 (desiredAccuracy) 减少不必要的能耗(精确度越低,精确度越低,能耗也越少)
/*
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;
*/
// 期望精确度
self.manager.desiredAccuracy = kCLLocationAccuracyBest;
- 无法获取定位的原因:
1.没有设置info.plist
2.mgr设置强引用
3.模拟器bug 切换同iOS版本的模拟器
- 完整代码:
#import "ViewController.h"
#import
@interface ViewController ()
@property (nonatomic,strong) CLLocationManager *manager;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 创建位置管理者
self.manager = [[CLLocationManager alloc]init];
// 请求授权
if ([self.manager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.manager requestWhenInUseAuthorization];
}
// 设置代理
self.manager.delegate = self;
// 开启定位
[self.manager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
CLLocation *location = locations.lastObject;
NSLog(@"%f,%f",location.coordinate.latitude,location.coordinate.longitude);
//[manager stopUpdatingLocation];停止定位(一次性定位)
}
- 计算两个位置间距离(直线距离):
CLLocation *location1 = [[CLLocation alloc]initWithLatitude:39.2 longitude:40.2];
CLLocation *location2 = [[CLLocation alloc]initWithLatitude:23.2 longitude:234.2];
CLLocationDistance distance = [location1 distanceFromLocation:location2];
NSLog(@"%f",distance);
- CLLocation 位置对象属性说明:
// 经纬度
@property(readonly, nonatomic) CLLocationCoordinate2D coordinate;
// 海拔,高度
@property(readonly, nonatomic) CLLocationDistance altitude;
// 水平精确度 用于描述经纬度测量值和真实值之间的误差范围
@property(readonly, nonatomic) CLLocationAccuracy horizontalAccuracy;
// 垂直精确度 用于描述高度测量值和真实值之间的误差范围
@property(readonly, nonatomic) CLLocationAccuracy verticalAccuracy;
// 航向
@property(readonly, nonatomic) CLLocationDirection course __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_2_2) __TVOS_PROHIBITED __WATCHOS_PROHIBITED;
// 瞬时速度
@property(readonly, nonatomic) CLLocationSpeed speed __OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_2_2) __TVOS_PROHIBITED __WATCHOS_PROHIBITED;
// 时间戳
@property(readonly, nonatomic, copy) NSDate *timestamp;
// 楼层 (iPhone 6 增加了气压传感器,之前只能通过海拔估算)
@property(readonly, nonatomic, copy, nullable) CLFloor *floor __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_8_0);
// 描述
@property (nonatomic, readonly, copy) NSString *description;