天天看點

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

來源:簡書

著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。