背景
我们在App使用过程中包含获取用户位置的需求,于是在工程的Info.plis中,我们包含“Location When In Use Usage Description”,即在获取用户定位信息时,弹窗获取用户授权显示的文案。
在某一次上传应用时,收到了苹果的邮件,提示需要包含“Location Always Use Usage Description”,如下图,由于本身并不会需要后台时获取用户位置信息,但是仍收到了邮件,于是猜测可能是第三方SDK里面包含了后台获取用户位置的代码被苹果提示,于是紧急按照邮件增加了此描述文案,但是发现第一次使用高德地图获取用户位置信息时,没有获取到用户位置信息,也没有弹窗进行询问用户后是否授权,,由于我们没有获得高德提供的获取位置信息成功或者失败的回调,导致用户某些功能无法使用,于是进行了以下调研。
获取授权认证的方法
在iOS8以后,获取用户位置信息的授权,需要
1.在Info.plis中配置Location When In Use Usage Description或者Location Always Use Usage Description。
2.调用CLLocationManager的方法:
前台获取位置信息授权:requestWhenInUseAuthorization
后台获取位置信息授权:requestAlwaysAuthorization
而在iOS11之后Info.plist中又出现了一条Location Always and When In Use Usage Description,顾名思义,这个描述与前后台获取定位都有关系。但具体关系在哪,还需要我们去摸索。
在iOS11的CLLocationManager中的有以下描述:
requestWhenInUseAuthorization:
The NSLocationWhenInUseUsageDescription key must be specified in your
Info.plist; otherwise, this method will do nothing, as your app will be
assumed not to support WhenInUse authorization.
requestAlwaysAuthorization:Both the NSLocationAlwaysAndWhenInUseUsageDescription andNSLocationWhenInUseUsageDescription keys must be specified in yourInfo.plist; otherwise, this method will do nothing, as your app will beassumed not to support Always authorization.
可见iOS11中在前台获取位置时,需要配置NSLocationWhenInUseUsageDescription,而在后台获取位置时,需要配置NSLocationAlwaysAndWhenInUseUsageDescription和NSLocationWhenInUseUsageDescription,而并没有Location Always Use Usage Description,由于我们也并不了解高德代码中具体调用的方法,于是做了下面的针对不同版本系统的研究,查看原因。
获取授权认证的研究
其中,Location When In Use Usage Description:“前台定位”,Location Always Use Usage Description:“后台定位”,
Location Always and When In Use Usage Description:“获取定位”。
如上图,可见,在iOS11中,苹果不允许用户单纯的允许后台获取位置的权限,将使用位置信息权限完全交给用户来选择,即如果app只使用前台获取位置,那么可以只配置Location When In Use Usage Description,但是系统设置中的权限列表也只会有“使用期间”和“永不”两个选项,但是当开发者配置了Location Always and When In Use Usage Description时,那么权限列表中则会出现“使用期间”、“永不”和“始终”三个选项。
经测试只配置了Location When In Use Usage Description或者Location Always Use Usage Description在iOS11中是不会弹窗询问授权的,我们之前的改动页确实造成了此问题。
具体情形,感兴趣的同学可以自己进行测试。
综上,为了保证在iOS8 和iOS11的设备上都能正确的进行弹窗获取授权,那么只存在三个可用的配置方式:
1.Location When In Use Usage Description,这样只能使用前台获取定位。
2.Location Always and When In Use Usage Description和Location When In Use Usage Description,这样在iOS8下能够获取前台定位授权,iOS11下前后台都能获取定位授权。
3.Location Always and When In Use Usage Description、Location When In Use Usage Description和Location Always Use Usage Description,则在iOS8 和 iOS11 时都可以获取前后台位置授权。
因此,得到如下建议:
1.如果想要使用后台获取定位,则三个文案都需要配置才能保证在iOS不同版本正常使用。
2.如果仅需要使用前台定位,需要包含Location When In Use Usage Description,不要配置Location Always Use Usage Description,是否使用Location Always and When In Use Usage Description都可,但因不知道是否第三方SDK中有后台获取定位的需求,因苹果进行邮件提醒,建议遵循新要求增加。
高德地图研究
在实际测验正确配置时发现,当调用requestWhenInUseAuthorization时,授权弹窗会使用Location When In Use Usage Description,
而当调用requestAlwaysAuthorization时,iOS11下会使用Location Always and When In Use Usage Description,而iOS8下会使用Location Always Use Usage Description。
当两个方法都调用时,会根据先调用的那个方法显示对应的文案,第二个不会弹窗询问。
值得注意的,在iOS11下当requestWhenInUseAuthorization已经获取完授权时,如果调用了requestAlwaysAuthorization,系统会再次弹窗询问是否允许适中获取位置信息,此弹窗只会出现一次,无论用户是否作出了选择。
基于上面的信息,我们发现高德地图在获取位置信息时,如果配置了Location When In Use Usage Description和Location Always and When In Use Usage Description时,高德地图弹窗的文案,与调用了requestWhenInUseAuthorization一致。当三个都配置了时,却与requestAlwaysAuthorization一致。
于是我们猜测,一种可能是高德两种情况调用的方法不一样,另外一种就是我们上面的理解存在问题,于是我们做了实验。
由于requestWhenInUseAuthorization和requestAlwaysAuthorization为CLLocationManager中的方法,我们无法看到其具体实现。于是我们给CLLocationManager写了一个分类,设置断点查看高德是否两种情况调用了不同的方法,事实证明确实如此,有可能高德判断了开发者配置的文案,来决定调用那个方法来显示弹窗,感兴趣的可以继续研究一下。
还有话说
苹果针对于获取授权这一块的描述并没有十分清晰明确,有些东西需要我们实际测试来辅助理解,上面的内容也仅仅是本人测试后的理解和分析,可能有理解不全面伸直的错误的地方,欢迎大家积极指出讨论,共同理解。转载请标明出处,谢谢。
原文地址
欢迎邮件沟通wangplus7@gmail.com,或者添加微信pmplus7。