定位demo(Obj-C)

需要导入头文件
补充说明,导入头文件后,系统会自动帮助导入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];

}

前台:


whenInUse.png

始终(前后台):

always.png

临时后台:开启临时后台设置:

定位demo(Obj-C)_第1张图片
background.png

IOS 9以后 后台或临时后台除了要设置info.plist文件外
都还需要代码允许后台模式,这样的好处是将不同的需求分离开,可以更省电(不同的位置管理者分开设置是否允许后台)

始终:NSLocationAlwaysUsageDescription
临时:NSLocationWhenInUseUsageDescription
self.manager.allowsBackgroundLocationUpdates = YES;
定位demo(Obj-C)_第2张图片
Authorization.png
  • 获取数据 设置代理 遵循协议 实现代理方法
@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;

你可能感兴趣的:(定位demo(Obj-C))