本文主要分享一下 iOS14 上对于隐私授权的变更和部分适配方案,仅做开发记录使用。
iOS14 的适配,很重要的一环就集中在用户隐私和安全方面。
在 iOS13 及以前,当用户首次访问应用程序时,会被要求开放大量权限,比如相册、定位、联系人,实际上该应用可能仅仅需要一个选择图片功能,却被要求开放整个照片库的权限,这确实是不合理的。对于相册,在 iOS14 中引入了 “LimitedPhotos Library” 的概念,用户可以授予应用访问其一部分的照片,对于应用来说,仅能读取到用户选择让应用来读取的照片,让我们看到了 Apple 对于用户隐私的尊重。这仅仅是一部分,在iOS14 中,可以看到诸多类似的保护用户隐私的措施,也需要我们升级适配。
▐ 定位
在 iOS13 及以前,App 请求用户定位授权时为如下形态:一旦用户同意应用获取定位信息,当前应用就可以获取到用户的精确定位。
iOS14 新增用户大致位置选项可供用户选择,原因是大多数 App 实际上并不需要获取用户到用户最准确的定位信息。iOS14 授权弹窗新增的 Precise的开关默认会选中精确位置。用户通过这个开关可以进行更改,当把这个值设为 On 时,地图上会显示精确位置;切换为Off时,将显示用户的大致位置。
对于对用户位置敏感度不高的 App 来说,这个似乎无影响,但是对于强依赖精确位置的 App 适配工作就显得非常重要了。可以通过用户在 “隐私设置” 中设置来开启精确定位,但是可能用户宁可放弃使用这个应用也不愿意开启。这个时候,iOS14 在 CLLocationManager 新增两个方法可用于向用户申请临时开启一次精确位置权限。
使用方式也很简单,需要首先在 Info.plist 中配置“NSLocationTemporaryUsageDescriptionDictionary”字典中需要配置 key 和 value 表明使用位置的原因,以及具体的描述。
对于地理位置不敏感的App 来说,iOS14 也可以通过直接在 info.plist 中添加 NSLocationDefaultAccuracyReduced 为 true 默认请求大概位置。
这样设置之后,即使用户想要为该 App 开启精确定位权限,也无法开启。
也可以直接通过API来根据不同的需求设置不同的定位精确度。
需要注意的是,当 App 在 Background 模式下,如果并未获得精确位置授权,那么 Beacon 及其他位置敏感功能都将受到限制。
▐ IDFA
IDFA 全称为 Identity for Advertisers ,即广告标识符。用来标记用户,目前最广泛的用途是用于投放广告、个性化推荐等。
在 iOS13 及以前,系统会默认为用户开启允许追踪设置,我们可以简单的通过代码来获取到用户的 IDFA 标识符。
但是在iOS14中,系统会默认为用户关闭广告追踪权限。我们还是通过同样的方法进行获取,但是我们需要先进行权限的申请(和使用定位相机一样),如果不申请权限,获取到的idfa 将会是 00000000-0000-0000-0000-000000000000
对于这种情况,我们需要去请求用户权限。首先需要在 Info.plist 中配置" NSUserTrackingUsageDescription " 及描述文案,接着使用 AppTrackingTransparency 框架中的 ATTrackingManager 中的 requestTrackingAuthorizationWithCompletionHandler 请求用户权限,在用户授权后再去访问 IDFA 才能够获取到正确信息。
在info.plist 中添加 权限申请描述
<key>NSUserTrackingUsageDescription</key>
<string>激活需要获取您的设备标识符</string>
进行权限判断,根据不同权限进行判断:
+ (NSString *)getIDFA {
// 需要导入头文件: #import <AppTrackingTransparency/AppTrackingTransparency.h> #import <AdSupport/AdSupport.h>
static NSString *IDFA = @"";
if (@available(iOS 14, *)) {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
if (status == ATTrackingManagerAuthorizationStatusAuthorized) { // 用户允许
IDFA = [[ASIdentifierManager sharedManager] advertisingIdentifier].UUIDString;
}
}];
} else {
// iOS 13之前使用原方式访问 IDFA
if ([[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]) {
IDFA = [[ASIdentifierManager sharedManager] advertisingIdentifier].UUIDString;
}
}
KLog(@"IDFA:%@", IDFA);
return IDFA;
}