iOS地图 -- 定位初使用

  • iOS的定位服务用到的框架是#import <CoreLocation/CoreLocation.h>
  • 定位中用到的类是CLLocationManager

一.iOS8.0之前的定位

  • 向用户描述授权的信息需要在info.plist中配以下key

  • 后台情况下开启定位服务需要进行如下图配置

二.iOS8.0之后的定位(包含iOS8.0)

  • iOS8.0之后前台定位授权和后台定位授权需要调用下面对应的方法
// 前台定位授权 官方文档中说明info.plist中必须有NSLocationWhenInUseUsageDescription键
[_mgr requestWhenInUseAuthorization];

或者

// 前后台定位授权 官方文档中说明info.plist中必须有NSLocationAlwaysUsageDescription键
[_mgr requestAlwaysAuthorization];

三.版本不同的适配问题(两种方法)

  • 方法一:
    // 方法一:判断iOS版本号
    if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {

        // 前台定位授权 官方文档中说明info.plist中必须有NSLocationWhenInUseUsageDescription键
        [_mgr requestWhenInUseAuthorization];
        // 前后台定位授权 官方文档中说明info.plist中必须有NSLocationAlwaysUsageDescription键
        [_mgr requestAlwaysAuthorization];
    }
  • 方法二:高大上的方法
    // 方法二:判断位置管理者能否响应iOS8之后的授权方法
    if ([_mgr respondsToSelector:@selector(requestAlwaysAuthorization)]) {

//            // 前台定位授权 官方文档中说明info.plist中必须有NSLocationWhenInUseUsageDescription键
//            [_mgr requestWhenInUseAuthorization];
        // 前后台定位授权 官方文档中说明info.plist中必须有NSLocationAlwaysUsageDescription键
        [_mgr requestAlwaysAuthorization];
    }

三.其余细节问题

  • 位置管理者的精确度
    /**
     kCLLocationAccuracyBestForNavigation; --> 最适合导航
     kCLLocationAccuracyBest; --> 最好的
     kCLLocationAccuracyNearestTenMeters; --> 附近10米
     kCLLocationAccuracyHundredMeters; --> 100米
     kCLLocationAccuracyKilometer; --> 1000米
     kCLLocationAccuracyThreeKilometers; --> 3000米
     */
    // 设置定位所需的精度 枚举值 精确度越高越耗电
    self.mgr.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
  • 位置管理者的过滤器,没移动制定的距离定位一次
    // 每100米更新一次定位
    self.mgr.distanceFilter = 100;

四.代理方法中获取定位到的位置信息,这里先不细讲,下一次笔记详细说明

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    NSLog(@"已经定位");
}

五.代理方法中监听授权状态的改变

// 代理方法中监听授权的改变,被拒绝有两种情况,一是真正被拒绝,二是服务关闭了
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    switch (status) {
        case kCLAuthorizationStatusNotDetermined:
        {
            NSLog(@"用户未决定");
            break;
        }
        // 系统预留字段,暂时还没用到
        case kCLAuthorizationStatusRestricted:
        {
            NSLog(@"受限制");
            break;
        }
        case kCLAuthorizationStatusDenied:
        {
            // 被拒绝有两种情况 1.设备不支持定位服务 2.定位服务被关闭
            if ([CLLocationManager locationServicesEnabled]) {
                NSLog(@"真正被拒绝");
                // 跳转到设置界面
                NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                if ([[UIApplication sharedApplication] canOpenURL:url]) {

                    [[UIApplication sharedApplication] openURL:url];
                }
            }
            else {
                NSLog(@"没有开启此功能");
            }
            break;
        }
        case kCLAuthorizationStatusAuthorizedAlways:
        {
            NSLog(@"前后台定位授权");
            break;
        }
        case kCLAuthorizationStatusAuthorizedWhenInUse:
        {
            NSLog(@"前台定位授权");
            break;
        }

        default:
            break;
    }
}

六.练习详细代码

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>

@interface ViewController ()<CLLocationManagerDelegate>
/** 位置管理者 */
@property(nonatomic,strong) CLLocationManager *mgr;
@end

@implementation ViewController

#pragma mark - 懒加载
- (CLLocationManager *)mgr
{
    if (_mgr == nil) {
        // 实例化位置管理者
        _mgr = [[CLLocationManager alloc] init];
        // 指定代理,代理中获取位置数据
        _mgr.delegate = self;

        // 兼容iOS8之后的方法
        // 方法一:判断iOS版本号
        if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {

            // 前台定位授权 官方文档中说明info.plist中必须有NSLocationWhenInUseUsageDescription键
            [_mgr requestWhenInUseAuthorization];
            // 前后台定位授权 官方文档中说明info.plist中必须有NSLocationAlwaysUsageDescription键
            [_mgr requestAlwaysAuthorization];
        }
        // 方法二:判断位置管理者能否响应iOS8之后的授权方法
        if ([_mgr respondsToSelector:@selector(requestAlwaysAuthorization)]) {

//            // 前台定位授权 官方文档中说明info.plist中必须有NSLocationWhenInUseUsageDescription键
//            [_mgr requestWhenInUseAuthorization];
            // 前后台定位授权 官方文档中说明info.plist中必须有NSLocationAlwaysUsageDescription键
            [_mgr requestAlwaysAuthorization];
        }
    }
    return _mgr;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // 开启位置更新
    [self.mgr startUpdatingLocation];

    /**
     kCLLocationAccuracyBestForNavigation; --> 最适合导航
     kCLLocationAccuracyBest; --> 最好的
     kCLLocationAccuracyNearestTenMeters; --> 附近10米
     kCLLocationAccuracyHundredMeters; --> 100米
     kCLLocationAccuracyKilometer; --> 1000米
     kCLLocationAccuracyThreeKilometers; --> 3000米
     */
    // 设置定位所需的精度 枚举值 精确度越高越耗电
    self.mgr.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    // 每100米更新一次定位
    self.mgr.distanceFilter = 100;
}

#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    NSLog(@"已经定位");
}

// 代理方法中监听授权的改变,被拒绝有两种情况,一是真正被拒绝,二是服务关闭了
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    switch (status) {
        case kCLAuthorizationStatusNotDetermined:
        {
            NSLog(@"用户未决定");
            break;
        }
        // 系统预留字段,暂时还没用到
        case kCLAuthorizationStatusRestricted:
        {
            NSLog(@"受限制");
            break;
        }
        case kCLAuthorizationStatusDenied:
        {
            // 被拒绝有两种情况 1.设备不支持定位服务 2.定位服务被关闭
            if ([CLLocationManager locationServicesEnabled]) {
                NSLog(@"真正被拒绝");
                // 跳转到设置界面
                NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                if ([[UIApplication sharedApplication] canOpenURL:url]) {

                    [[UIApplication sharedApplication] openURL:url];
                }
            }
            else {
                NSLog(@"没有开启此功能");
            }
            break;
        }
        case kCLAuthorizationStatusAuthorizedAlways:
        {
            NSLog(@"前后台定位授权");
            break;
        }
        case kCLAuthorizationStatusAuthorizedWhenInUse:
        {
            NSLog(@"前台定位授权");
            break;
        }

        default:
            break;
    }
}

@end

原文地址:https://www.cnblogs.com/gchlcc/p/5843531.html