iOS14隐私权限适配及其他

Overview

WWDC2020发布会上苹果展示了新的iOS14系统。对于iOS开发工程师来说,适配iOS14其重点在于隐私权限的适配。具体内容可以观看WWDC2020中:建立更好的隐私信任的视频进行了解。

note:截止目前,适配iOS14需要更新mac系统到11 beta 6、xcode需要更新到12 beta 6、手机需要更新到14 beta 8,相关版本可以到苹果官网下载;更新beta版本打包可能会影响正常上架,该问题未进行测试,但需要引起注意。

广告标识符的获取

广告标识符(Identity for Advertisers)简称IDFA,主要用来标记用户。在iOS14系统中,系统会默认关闭广告标跟踪权限。如果在开发中使用,需要向用户请求权限,步骤如下:

1、info.plist配置

选中info.plist右键Open As->Source Code 然后将下方配置和描述信息添加进去。

 

<key>NSUserTrackingUsageDescription</key>
<string>“太平通宝”需要您允许访问广告标识符权限,以便于追踪广告和信息的推送</string>

2、头文件引入

为了适配低版本Xcode编译,需要使用预编译命令,所以头文件引入方式如下所示:

 

#if defined(__IPHONE_14_0)
#import <AppTrackingTransparency/AppTrackingTransparency.h>//适配iOS14
#endif

3、获取IDFA

iOS14及以上系统,需要先请求跟踪权限,用户同意后才能获取广告标识。获取方法标识符的代码iOS14之前一样。示例代码如下所示:

 

+ (NSString *)idfaString {
    __block NSString *idfa;
#if defined(__IPHONE_14_0)
    if (@available(iOS 14, *)) {
        // iOS14及以上版本需要先请求权限
        ATTrackingManagerAuthorizationStatus status = ATTrackingManager.trackingAuthorizationStatus;
        if (status == ATTrackingManagerAuthorizationStatusNotDetermined) { //用户未做选择或未弹窗
            dispatch_semaphore_t sem = dispatch_semaphore_create(0);
            [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
                // 获取到权限后,依然使用老方法获取idfa
                if (status == ATTrackingManagerAuthorizationStatusAuthorized) { //用户允许
                    idfa = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];
                    ICLog(@"--iOS14----%@----",idfa);
                }
                dispatch_semaphore_signal(sem);
            }];
            dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
        }else if(status == ATTrackingManagerAuthorizationStatusAuthorized){//用户允许
            idfa = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];
        }else{
            ICLog(@"请在设置-隐私-Tracking中允许App请求跟踪");
        }
    }
#else
    // iOS14以下版本依然使用老方法
    // 判断在设置-隐私里用户是否打开了广告跟踪
    if ([[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]) {
        idfa = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];
        ICLog(@"---iOS14以下系统----%@-----",idfa);
    } else {
        ICLog(@"请在设置-隐私-广告中打开广告跟踪功能");
    }
#endif
    idfa = (idfa ? : @"");
    return idfa;
}

相册权限

iOS14中新增了个有限的图片库访问模式,在授权弹窗的时候会新增个Select Photo选项,用户可以选择一部分图片供App读取,而App无法获取相册中的所有图片信息。

如果用户使用了有限图片库访问(Limited Photo Library Access)的模式, 如果App不进行适配,权限提示框会在每次冷启动打开相册的时候重新弹出,我们需要在info.plist中进行配置,关闭弹窗。

1、info.plist配置

选中info.plist右键Open As->Source Code 然后将下方配置和描述信息添加进去。

 

<key>PHPhotoLibraryPreventAutomaticLimitedAccessAlert</key>
<true/>

当然,我们也可以通过相应API来控制何时弹出图片选择的弹出。API如下所示:

 

[[PHPhotoLibrary sharedPhotoLibrary] presentLimitedLibraryPickerFromViewController:self];

同时,在iOS14中官方推荐使用苹果推荐使用PHPicker来代替原API来选择图片。

关于PHPicker的介绍可以参看WWDC2020:认识新的照片选择器的相关介绍。

位置信息

在iOS14中,苹果新增了模糊定位的概念。原因是苹果认为很多APP并不需要获取用户的精准定位。所以在iOS14授权弹窗的时候新增了Precise的精准开关,默认会选中精准位置,用户可以通过这个开关进行更改。

对于地理位置敏感的APP

1、info.plist配置

不过对于需要精准定位的App需要在info.plist中设置NSLocationTemporaryUsageDescriptionDictionary字典,key为purposeKey,value为对应获取精准定位的原因。

示例如下:

 

<key>NSLocationTemporaryUsageDescriptionDictionary</key>
    <dict>
        <key>punchTheClock</key>
        <string>“太平通宝”需要您允许精准定位,以便于使用打卡功能</string>
    </dict>

2、获取单次精准定位

同时需要调用相应API,获取精准定位。代码如下:

 

[CALocationMnanger requestTemporaryFullAccuracyAuthorizationWithPurposeKey:@"punchTheClock"]

对于地理位置不敏感的App

对定位信息不敏感的APP,iOS14中可以直接在info.plist中添加NSLocationDefaultAccuracyReducedtrue,默认请求模糊定位

选中info.plist右键Open As->Source Code 然后将下方配置和描述信息添加进去。

 

<key>NSLocationDefaultAccuracyReduced</key>
<true/>

Local Network

iOS14中新增了Local Network权限提示,具体关于Local Network的相关信息可以查看苹果官网的视频或者少数派的关于iOS14新增的本地网络权限,要开给第三方App吗?等相关资料。

剪贴板

在iOS14中,如果APP读取剪切版的内容时,手机会弹出提示,提示哪个APP在获取剪切板内容。

相机和麦克风

在iOS14中APP如果使用相机和麦克风,手机的的上方会有绿色和黄色的提示,同时也可以查看是哪个APP在使用相机和麦克风。

关于该功能开发人员无法控制。

UIDatePicker更新UI样式

在iOS14中,UIDatePicker的样式新增了UIDatePickerStyleInline,而且为默认值。如果项目中使用了UIDatePicker,而且希望使用原来的样式,需要设置其样式。

 

 self.pickerView.preferredDatePickerStyle = UIDatePickerStyleWheels;

UITableViewCell适配

UITableViewCell无法点击

在Xcode12、iOS14中,如果在UITableViewCell渲染前没有调用self.contentView,系统会在渲染完UITableViewCell上的控件后在其上方添加contentView,这会使contentView拦截住UITableViewCell控件的响应事件。

其解决方式是将UITableViewCell上的控件添加到self.contentView

 

[self addSubview:view];
改为:
[self.contentView addSubview:view];

hook修复UITableViewCell无法点击问题

虽然上方的方法可以修复UITableViewCell无法点击问题,但对于一个很庞大的项目来说,不确定是否有遗漏,尤其是一些组件。所以在项目中需要用到修改+hook的方式。

方法也很简单,直接hook住UITableViewCell中的addSubview:方法,全局修复下即可,同时后期写代码也要注意代码规范。

 

#import "UITableViewCell+TB.h"
#import <objc/runtime.h>

@implementation UITableViewCell (TB)

+ (void)load {
    Method method1 = class_getInstanceMethod([self class], NSSelectorFromString(@"addSubview:"));
    Method method2 = class_getInstanceMethod([self class], @selector(tb_addSubview:));
    method_exchangeImplementations(method1, method2);
}

- (void)addSubview:(UIView *)view{
    [super addSubview:view];
}

- (void)tb_addSubview:(UIView *)view {
    if  ([view isKindOfClass:NSClassFromString(@"UITableViewCellContentView")]) {
        [self tb_addSubview:view];
    } else {
        [self.contentView addSubview:view];
    }
}

@end

UITableViewCell 背景色变成灰色

灰色为self.contentView的背景色,在init方法中共添加即可。

YYAnimatedImageView 无法加载图片

因为项目中用到YYImage第三方库。

解决方式:
修复:YYAnimatedImageView.m 529行的函数修改如下:

 

- (void)displayLayer:(CALayer *)layer {
    if (_curFrame) {
        layer.contents = (__bridge id)_curFrame.CGImage;
    }else {
        if (@available(iOS 14.0, *)) {
            [super displayLayer:layer];
        }
    }
}

但在项目中,并不会这些修复,毕竟是第三方库,我们可以直接替换这个类的该方法。

代码如下:

 

#import "YYAnimatedImageView+TB.h"
#import <objc/runtime.h>

@implementation YYAnimatedImageView (TB)

+ (void)load {
    Method method1 = class_getInstanceMethod([self class], NSSelectorFromString(@"displayLayer:"));
    Method method2 = class_getInstanceMethod([self class], @selector(tb_displayLayer:));
    method_exchangeImplementations(method1, method2);
}

- (void)tb_displayLayer:(CALayer *)layer{
    Ivar ivar = class_getInstanceVariable(self.class, "_curFrame");
    UIImage *_curFrame = object_getIvar(self, ivar);
    if (_curFrame) {
        layer.contents = (__bridge id)_curFrame.CGImage;
    }else{
        if (@available(iOS 14.0, *)) {
            [super displayLayer:layer];
        }
    }
}

@end

写在最后

关于真机调试

最新Xcode 12 beta版本31G,而且还不稳定,如果需要使用低版本Xcode运行到iOS14的真机上可以下载iOS14的DeviceSupport,存放的路径为:

 

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport

关于更新iOS14系统

关于更新iOS14 beta版的系统,我在百度经验上水了篇文章,可以点击百度经验查看,当然经验水的有些粗糙,还有错别字。

也可能是好久没写了,写完后,竟然还给了0.3元的红包……

参考资料



作者:拿根针尖对麦芒
链接:https://www.jianshu.com/p/fd82a1ea0106
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值