天天看点

iOS14隐私权限适配及其他Overview广告标识符的获取相册权限位置信息Local Network剪贴板相机和麦克风UIDatePicker更新UI样式UITableViewCell适配YYAnimatedImageView 无法加载图片写在最后参考资料

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

中添加

NSLocationDefaultAccuracyReduced

true

,默认请求

模糊定位

选中

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元的红包……

参考资料

  • WWDC2020
  • WWDC2020中:建立更好的隐私信任
  • WWDC2020:认识新的照片选择器
  • WWDC2020-在你的应用程序中支持本地网络隐私
  • iOS14新增的本地网络权限,要开给第三方App吗?
  • iOS14 隐私适配及部分解决方案
  • iOS14 适配 先行者
  • iOS14:DeviceSupport

作者:拿根针尖对麦芒

链接:https://www.jianshu.com/p/fd82a1ea0106

来源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。