iOS开发-浅谈定位权限

2018-09-04  本文已影响0人  Engandend

[TOC]

在iOS8之后,关于权限信息有些更改
对于定位权限而言,相对其他的权限稍微麻烦一些

1、key的配置

1、使用app的时候使用位置信息

NSLocationWhenInUseUsageDescription

2、允许app一直使用位置信息

NSLocationAlwaysUsageDescription

3、允许2中选择同时存在 11.4之后有用

NSLocationAlwaysAndWhenInUseUsageDescription

2、api的调用

有2个api:

requestWhenInUseAuthorization    //when-in-use
requestAlwaysAuthorization        //Always

这2个api从表面来看,意思是请求when-in-useAlways
但是实测发现when-in-use完全可以覆盖Always,也就是说Always完全可以不用,让when-in-use 根据plist中的key配置自动去完成所需要的权限弹框。

具体测试如下:
1)、11.4系统以下(上面说到 alwayandwhen 对11.4以下无用,这里不测试)

配置信息 requestWhenInUseAuthorization requestAlwaysAuthorization
1 请求1 无效
2 请求2 请求2
1 2 请求2 请求2

2)、11.4系统以后

配置信息 requestWhenInUseAuthorization requestAlwaysAuthorization
1 请求1 无效
2 无效 无效
3 无效 无效
1 2 请求1 无效
1 3 请求1、2 请求1、2
1 2 3 请求1、2 请求1、2

基于以上测试结果, 我们可以发现:
11.4之前的系统:
12可以单独存在。
11.4之后的系统:
所有的权限必须基于1而存在。

在app开发中,现在一般最低适配的系统是8或者9,所以在plist中配置key的时候,1是必须的,如果需要用到一直使用位置权限,那么1 2 3 3个key都需要配置

3、权限请求

对于app中权限的请求,相册、相机等都有系统提供的api直接去请求权限,但是位置信息比较麻烦,在这里做了一个封装:
具体代码如下:
JEAuthorityTool.h文件
引入系统库 #import <CoreLocation/CoreLocation.h>


/**
 请求定位权限

 @param block 结果
 */
+(void)je_authorityLocationRequest:(void(^)(BOOL granted,
                                            CLAuthorizationStatus status))block;

/**
 *  获取定位使用权限
 *
 *  @param location BOOL 表示系统所有app有没有打开定位  status app的定位权限状态
*/
+(void)je_authorityLocation:(void(^)(BOOL canLocation ,
                                     CLAuthorizationStatus status))location;

JEAuthorityTool.m文件

#import "JEAuthorityTool.h"

typedef void(^je_authorityLocationBLock)(BOOL granted,CLAuthorizationStatus state);

@interface JEAuthorityTool ()<CLLocationManagerDelegate>

@property (strong,  nonatomic)  CLLocationManager   *locationManager;
@property (copy,    nonatomic)  je_authorityLocationBLock   locationBlock;

@end


static  dispatch_once_t onceToken;
+ (JEAuthorityTool *)sharedLocationManage
{
    static  JEAuthorityTool *__singletion;
    dispatch_once(&onceToken, ^{
        __singletion=[[self alloc] init];
    });
    return __singletion;
}
-(instancetype)init
{
    if (self = [super init])
    {
        self.locationManager = [CLLocationManager new];
    }
    return self;
}

+(void)je_authorityLocationRequest:(void(^)(BOOL granted,
                                            CLAuthorizationStatus status))block
{
    [self sharedLocationManage].locationBlock = block;
    
    BOOL canUser;
    CLAuthorizationStatus status;
    [self je_authorityLocation:&canUser status:&status];
    
    if (status == kCLAuthorizationStatusNotDetermined)
    {
        CLLocationManager *manager = [self sharedLocationManage].locationManager;
        manager.delegate = [self sharedLocationManage];
        [manager requestWhenInUseAuthorization];
        
        NSDictionary *dic = [NSBundle mainBundle].infoDictionary;
        BOOL boolWhen = locationContentWithStr(@"NSLocationWhenInUseUsageDescription",dic);
        BOOL boolAlway = locationContentWithStr(@"NSLocationAlwaysUsageDescription",dic);
        
        BOOL show = NO;
        if (@available(iOS 11.4, *))
            show = boolWhen;
        else
            show = (boolAlway || boolWhen);
        
        if (!show) {
            NSLog(@"---------------------\n\
                  ⚠️如果第一次没有弹出权限请求\n\
                  请在plist中配置位置权限信息\n\
                  按照实际需求,需要配置以下key\n\
                  NSLocationWhenInUseUsageDescription   和\n\
                  NSLocationAlwaysUsageDescription      和\n\
                  NSLocationAlwaysAndWhenInUseUsageDescription\n\
                  ---------------------");
        }
    }
    else{
        if ([self sharedLocationManage].locationBlock)
        {
            [self sharedLocationManage].locationBlock(canUser, status);
            [self sharedLocationManage].locationBlock = nil;
        }
        [self sharedLocationManage].locationManager = nil;
        onceToken = 0;
    }
}

BOOL locationContentWithStr(NSString *str, NSDictionary *dic)
{
    if ([[dic allKeys] containsObject:str])
    {
        id value =  dic[str];
        if ([value isKindOfClass:[NSString class]])
        {
            return YES;
        }
    }
    return NO;
}


-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    if (status != kCLAuthorizationStatusNotDetermined)
    {
        if (self.locationBlock) {
            self.locationBlock([[self class] je_authorityBoolLocation ], status);
            self.locationBlock = nil;
        }
        self.locationManager = nil;
        onceToken = 0;
    }
}

+(void)je_authorityLocation:(void (^)(BOOL, CLAuthorizationStatus))location
{
    if (location) {
        if (![CLLocationManager locationServicesEnabled]) {
            NSLog(@"系统所有app都没有打开定位功能");
            location(NO,kCLAuthorizationStatusDenied);
            return;
        }
        
        CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
        location(YES,status);
    }
}

+(void)je_authorityLocation:(BOOL *)systemOpen status:(CLAuthorizationStatus *)status
{
    if (![CLLocationManager locationServicesEnabled]) {
        NSLog(@"系统所有app都没有打开定位功能");
        
        *systemOpen = NO;
        *status = kCLAuthorizationStatusDenied;
    }
    else
    {
        *systemOpen = YES;
        *status = [CLLocationManager authorizationStatus];
    }
}

+(BOOL)je_authorityBoolLocation
{
    BOOL systemOpen;
    CLAuthorizationStatus status;
    [self je_authorityLocation:&systemOpen status:&status];
    if (systemOpen == NO) {
        return NO;
    }
    else
    {
        if (status == kCLAuthorizationStatusNotDetermined ||
            status == kCLAuthorizationStatusAuthorizedAlways ||
            status == kCLAuthorizationStatusAuthorizedWhenInUse)
        {
            return YES;
        }
        else{
            return NO;
        }
    }
}

修改补充:

(2018-10-30)

1、2楼的兄弟提到Privacy - Location Usage Description(NSLocationUsageDescription),这个是iOS6-8的时候才使用的一个位置权限配置key,iOS8以后就舍弃了这个,因为在8之前,没有“使用时定位”和“一直定位”的区分。
如果要适配8之前的系统,如果能加的话还是要加上(我目前的项目都是最低适配8,而且模拟器最低也只能下到8.1的版本,所以无法测试)。参考链接(在页面内搜索NSLocationUsageDescription)

上一篇下一篇

猜你喜欢

热点阅读