#import "ViewController.h"// 0. 导入头文件#import <CoreLocation/CoreLocation.h>@interface ViewController () <CLLocationManagerDelegate>/** 位置管理者 */@PRoperty (nonatomic, strong) CLLocationManager *manager;@end@implementation ViewController- (CLLocationManager *)manager{ if (!_manager) { // 1. 创建CLLocationManager _manager = [[CLLocationManager alloc] init]; // 2. 设置代理 _manager.delegate = self; // 每隔多少米定位一次 _manager.distanceFilter = 100; /** kCLLocationAccuracyBestForNavigation // 最适合导航 kCLLocationAccuracyBest; // 最好的精确度,仅次于kCLLocationAccuracyBestForNavigation kCLLocationAccuracyNearestTenMeters; // 附近10m kCLLocationAccuracyHundredMeters; // 100m kCLLocationAccuracyKilometer; // 1千米 kCLLocationAccuracyThreeKilometers; // 3千米 */ // 设置定位精确度 // 并不是精确度越高就越好,精确度越高,就越耗性能,越费电,要根据需求来设置精确度 _manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; } return _manager;}- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ // 3.开始更新地址 // 此处重点:一定要在info.plist文件中加上key:Privacy - Location Usage Description,value可以随便写 [self.manager startUpdatingLocation];}#pragma mark - 实现CLLocationManagerDelegate代理方法// 4.实现代理方法- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ CLLocation *location = [locations lastObject]; NSLog(@"%@ -- %f", location.description, location.speed);}@end
解决方案:
(1)调用iOS 8.0的API,主动请求用户授权
(2)务必在info.plist文件中配置对应的键值, 否则以上请求授权的方法不生效
NSLocationAlwaysUsageDescription : 允许在前后台获取GPS的描述
NSLocationWhenInUseDescription : 允许在前台获取GPS的描述
#import "ViewController.h"#import <CoreLocation/CoreLocation.h>@interface ViewController () <CLLocationManagerDelegate>/** 位置管理者 */@property (nonatomic, strong) CLLocationManager *manager;@end@implementation ViewController- (CLLocationManager *)manager{ if (_manager == nil) { _manager = [[CLLocationManager alloc] init]; _manager.delegate = self; // 采取前台定位 // 1. 需要在info.plist文件中添加key:NSLocationWhenInUseUsageDescription // 2. 如果需要在后台继续定位,需要勾选后台模式,当程序进入后台后,会在最上方出现一个蓝条// [_manager requestWhenInUseAuthorization]; // 采用前后台定位 // 1. 需要在info.plist文件中添加NSLocationAlwaysUsageDescription这个key // 2. 这种模式的后台定位,不需要勾选后台模式,也不会出现蓝条 [_manager requestAlwaysAuthorization]; // requestWhenInUseAuthorization和requestAlwaysAuthorization请求同时存在: // 1. requestWhenInUseAuthorization请求在前,会先弹出前台授权描述,第二次启动程序的时候,还会弹出前后台授权描述 // 2. requestAlwaysAuthorization在前,只会弹出前后台授权描述,不会弹出前台授权描述. } return _manager;}- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ [self.manager startUpdatingLocation];}#pragma mark - <CLLocationManagerDelegate>/** * 更新定位 * * @param manager 位置管理器 * @param locations 定位的位置数组 */- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ NSLog(@"定位了");}
_manager.allowsBackgroundLocationUpdates = YES;
iOS 9.0 可以单次请求用户位置:-(void)requestLocation
- (void)requestLocation-(void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations // 成功调用-(void)locationManager:(nonnull CLLocationManager *)manager didFailWithError:(nonnull NSError *)error // 失败调用
/** * 代理方法: 更新定位 * * @param manager 位置管理器 * @param locations 定位的位置数组 */- (void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations{ // CLLocation常用属性 // coordinate (当前位置所在的经纬度) // altitude (海拔) // speed (当前速度) // course (航向) // -distanceFromLocation (获取两个位置之间的直线物理距离) CLLocation *location = [locations lastObject]; // 1. 获取偏向角度 NSString *angleStr = nil; switch ((int)location.course / 90) { case 0: angleStr = @"北偏东"; break; case 1: angleStr = @"东偏南"; break; case 2: angleStr = @"南偏西"; break; case 3: angleStr = @"西偏北"; break; default: angleStr = @"未知位置"; break; } // 2. 偏移角度 NSInteger angle = (int)location.course % 90; if (angle == 0) { // 表示正方向 angleStr = [angleStr substringWithRange:NSMakeRange(0, 1)]; } // 3. 移动了多少米 double distance = 0; if (_oldLocation) { distance = [location distanceFromLocation:_oldLocation]; } _oldLocation = location; // 4. 打印 NSString *locationStr = [NSString stringWithFormat:@"%@%zd度方向,移动了%.2fm", angleStr, angle, distance]; NSLog(@"%@", locationStr);}
kCLAuthorizationStatusNotDetermined = 0, // 用户未决定 kCLAuthorizationStatusRestricted, // 受限制 kCLAuthorizationStatusDenied, // 拒绝 kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(NA, 8_0), // 永久授权 kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0), // APP使用的时候授权
新闻热点
疑难解答