#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使用的时候授权