做者|盛蘭雅(嵐遙)ios
編輯|橙子君算法
出品|阿里巴巴新零售淘系技術macos
在剛剛結束的線上 WWDC 2020 發佈會上蘋果向咱們展現了新的 iOS14 系統。iOS14 的適配,很重要的一環就集中在用戶隱私和安全方面。小程序
在 iOS13 及之前,當用戶首次訪問應用程序時,會被要求開放大量權限,好比相冊、定位、聯繫人,實際上該應用可能僅僅須要一個選擇圖片功能,卻被要求開放整個照片庫的權限,這確實是不合理的。對於相冊,在 iOS14 中引入了 「LimitedPhotos Library」 的概念,用戶能夠授予應用訪問其一部分的照片,對於應用來講,僅能讀取到用戶選擇讓應用來讀取的照片,讓咱們看到了 Apple 對於用戶隱私的尊重。這僅僅是一部分,在iOS14 中,能夠看到諸多相似的保護用戶隱私的措施,也須要咱們升級適配。安全
最近在調研 iOS14的適配方案,本文主要分享一下 iOS14 上對於隱私受權的變動和部分適配方案,歡迎補充指正。bash
iOS14 新增了「Limited Photo Library Access」 模式,在受權彈窗中增長了 Select Photo 選項。用戶能夠在 App 請求調用相冊時選擇部分照片讓 App 讀取。從 App 的視⻆來看,你的相冊裏就只有這幾張照片,App 沒法得知其它照片的存在。網絡
iOS14 中當用戶選擇 「PHAuthorizationStatusLimited」 時,若是未進行適配,有可能會在每次觸發相冊功能時都進行彈窗詢問用戶是否須要修改照片權限。session
對於這種狀況可經過在Info.plist中設置「PHPhotoLibraryPreventAutomaticLimitedAccessAlert」的值爲 YES 來阻止該彈窗反覆彈出,而且可經過下面這個API來主動控制什麼時候彈出PHPickerViewController 進行照片選擇。app
[[PHPhotoLibrary sharedPhotoLibrary] presentLimitedLibraryPickerFromViewController:self];
複製代碼
在 iOS14 中官方推薦使用 PHPicker 來替代原 API 進行圖片選擇。PHPicker 爲獨立進程,會在視圖最頂層進行展現,應用內沒法對其進行截圖也沒法直接訪問到其內的數據。框架
一、UIImagePickerController -> PHPickerViewController, UIImagePickerViewController 功能受限,每次只能選擇一張圖片,將逐漸被廢棄。
二、PHPicker 支持多選,支持搜索,支持按 image,video,livePhotos 等進行選擇。
新API及遷移demo:
@interface ViewController () <PHPickerViewControllerDelegate>
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (nonatomic, strong) NSArray<NSItemProvider *> *itemProviders;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (IBAction)button:(id)sender {
// 如下 API 僅爲 iOS14 only
PHPickerConfiguration *configuration = [[PHPickerConfiguration alloc] init];
configuration.filter = [PHPickerFilter videosFilter]; // 可配置查詢用戶相冊中文件的類型,支持三種
configuration.selectionLimit = 0; // 默認爲1,爲0時表示可多選。
PHPickerViewController *picker = [[PHPickerViewController alloc] initWithConfiguration:configuration];
picker.delegate = self;
// picker vc,在選完圖片後須要在回調中手動 dismiss
[self presentViewController:picker animated:YES completion:^{
}];
}
#pragma mark - Delegate
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results {
[picker dismissViewControllerAnimated:YES completion:nil];
if (!results || !results.count) {
return;
}
NSItemProvider *itemProvider = results.firstObject.itemProvider;
if ([itemProvider canLoadObjectOfClass:UIImage.class]) {
__weak typeof(self) weakSelf = self;
[itemProvider loadObjectOfClass:UIImage.class completionHandler:^(__kindof id<NSItemProviderReading> _Nullable object, NSError * _Nullable error) {
if ([object isKindOfClass:UIImage.class]) {
__strong typeof(self) strongSelf = weakSelf;
dispatch_async(dispatch_get_main_queue(), ^{
strongSelf.imageView.image = (UIImage *)object;
});
}
}];
}
}
複製代碼
須要注意的是,在 limit Photo 模式下,AssetsLibrary 訪問相冊會失敗;在 writeOnly 模式下,AssetLibrary 也會有顯示問題。建議還在使用 AssetsLibrary 的同窗儘快遷移到新 API。
受權相關:舊 API 廢棄,增長 PHAccessLevel 參數。若是再使用之前的API來獲取權限狀態, PHAuthorizationStatusLimited 狀態下也會返回 PHAuthorizationStatusAuthorized
typedef NS_ENUM(NSInteger, PHAccessLevel) {
PHAccessLevelAddOnly = 1, // 僅容許添加照片
PHAccessLevelReadWrite = 2, // 容許訪問照片,limitedLevel 必須爲 readWrite
} API_AVAILABLE(macos(10.16), ios(14), tvos(14));
// 查詢權限
PHAccessLevel level = PHAccessLevelReadWrite;
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatusForAccessLevel:level];
switch (status) {
case PHAuthorizationStatusLimited:
NSLog(@"limited");
break;
case PHAuthorizationStatusDenied:
NSLog(@"denied");
break;
case PHAuthorizationStatusAuthorized:
NSLog(@"authorized");
break;
default:
break;
}
// 請求權限,需注意 limited 權限盡在 accessLevel 爲 readAndWrite 時生效
[PHPhotoLibrary requestAuthorizationForAccessLevel:level handler:^(PHAuthorizationStatus status) {
switch (status) {
case PHAuthorizationStatusLimited:
NSLog(@"limited");
break;
case PHAuthorizationStatusDenied:
NSLog(@"denied");
break;
case PHAuthorizationStatusAuthorized:
NSLog(@"authorized");
break;
default:
break;
}
}];
複製代碼
在 iOS13 及之前,App 請求用戶定位受權時爲以下形態:一旦用戶贊成應用獲取定位信息,當前應用就能夠獲取到用戶的精肯定位。
iOS14 新增用戶大體位置選項可供用戶選擇,緣由是大多數 App 實際上並不須要獲取用戶到用戶最準確的定位信息。iOS14 受權彈窗新增的 Precise的開關默認會選中精確位置。用戶經過這個開關能夠進行更改,當把這個值設爲 On 時,地圖上會顯示精確位置;切換爲Off時,將顯示用戶的大體位置。
對於對用戶位置敏感度不高的 App 來講,這個彷佛無影響,可是對於強依賴精確位置的 App 適配工做就顯得很是重要了。能夠經過用戶在 「隱私設置」 中設置來開啓精肯定位,可是可能用戶寧肯放棄使用這個應用也不肯意開啓。這個時候,iOS14 在 CLLocationManager 新增兩個方法可用於向用戶申請臨時開啓一次精確位置權限。
使用方式也很簡單,須要首先在 Info.plist 中配置「NSLocationTemporaryUsageDescriptionDictionary」字典中須要配置 key 和 value 代表使用位置的緣由,以及具體的描述。
在本例中,key 即爲獲取用戶權限時傳的 "purposeKey",最終呈現給用戶的就是左圖,右圖爲當App主動關閉精肯定位權限申請。
對於地理位置不敏感的App 來講,iOS14 也能夠經過直接在 info.plist 中添加 NSLocationDefaultAccuracyReduced 爲 true 默認請求大概位置。
這樣設置以後,即便用戶想要爲該 App 開啓精肯定位權限,也沒法開啓。
也能夠直接經過API來根據不一樣的需求設置不一樣的定位精確度。
須要注意的是,當 App 在 Background 模式下,若是並未得到精確位置受權,那麼 Beacon 及其餘位置敏感功能都將受到限制。
iOS14 當 App 要使用 Bonjour 服務時或者訪問本地局域網,使用 mDNS 服務等,都須要受權,開發者須要在 Info.plist 中詳細描述使用的爲哪一種服務以及用途。下圖爲須要無需申請權限與須要受權的服務:
在 "隱私設置" 中也能夠查看和修改具體有哪些 App 正在使用 LocalNetwork
若是應用中須要使用 LocalNetwork 須要在 Info.plist 中配置兩個選項,詳細描述爲何須要使用該權限,以及須要列出具體使用 LocalNetwork 的服務列表。
對於使用了下列包含 Bonjour 的 framework,都須要更新描述.
iOS8 - iOS13 ,用戶在不一樣的網絡間切換和接入時,mac 地址都不會改變,這也就使得網絡運營商仍是能夠經過 mac 地址對用戶進行匹配和用戶信息收集,生成完整的用戶信息。iOS14 提供 Wifi 加密服務,每次接入不一樣的 WiFi 使用的 mac 地址都不一樣。每過 24 小時,mac 地址還會更新一次。須要關注是否有使用用戶網絡 mac 地址的服務。
下圖爲 iOS13 及以前用戶接入網絡時 mac 地址並不會進行改變
下圖爲 iOS14 用戶接入 Wi-Fi 時 mac 地址的變化狀況
而且用戶也能夠自行選擇是否開啓 private Wi-Fi address
在 iOS14 中,讀取用戶剪切板的數據會彈出提示。
彈出提示的緣由是使用 UIPasteboard 訪問用戶數據,訪問如下數據都會彈出 toast 提示。
兼容方案:若是應用訪問剪切板僅僅用於判斷是否爲URL格式,則 iOS14 新增了兩個 API 能夠用於規避該提示。若是應用想直接訪問剪切板的數據,暫時可能沒法作到規避該提示。iOS14 新增兩種 UIPasteboardDetectionPattern。
上面的兩個 API 可用於規避提示,但只能用於判斷剪切板中是否有 URL,並非真正的訪問剪貼板數據,也拿不到剪切板的真實數據。下面兩個 API 能夠得到具體的 URL 信息,可是會觸發剪切板提示。而且實測當用戶剪切板中包含多個 URL 時只會返回第一個。
使用示例
NSSet *patterns = [[NSSet alloc] initWithObjects:UIPasteboardDetectionPatternProbableWebURL, nil];
[[UIPasteboard generalPasteboard] detectPatternsForPatterns:patterns completionHandler:^(NSSet<UIPasteboardDetectionPattern> * _Nullable result, NSError * _Nullable error) {
if (result && result.count) {
// 當前剪切板中存在 URL
}
}];
複製代碼
iOS14 中 App 使用相機和麥克風時會有圖標提示以及綠點和黃點提示,而且會顯示當前是哪一個 App 在使用此功能。咱們沒法控制是否顯示該提示。
會觸發錄音小黃點的代碼示例:
AVAudioRecorder *recorder = [[AVAudioRecorder alloc] initWithURL:recorderPath settings:nil error:nil];
[recorder record];
複製代碼
觸發相機小綠點的代碼示例:
AVCaptureDeviceInput *videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:videoCaptureDevice error:nil];
AVCaptureSession *session = [[AVCaptureSession alloc] init];
if ([session canAddInput:videoInput]) {
[session addInput:videoInput];
}
[session startRunning];
複製代碼
IDFA 全稱爲 Identity for Advertisers ,即廣告標識符。用來標記用戶,目前最普遍的用途是用於投放廣告、個性化推薦等。
在 iOS13 及之前,系統會默認爲用戶開啓容許追蹤設置,咱們能夠簡單的經過代碼來獲取到用戶的 IDFA 標識符。
if ([[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]) {
NSString *idfaString = [[ASIdentifierManager sharedManager] advertisingIdentifier].UUIDString;
NSLog(@"%@", idfaString);
}
複製代碼
可是在 iOS14 中,這個判斷用戶是否容許被追蹤的方法已經廢棄。
iOS14 中,系統會默認爲用戶關閉廣告追蹤權限。
✎ 對於這種狀況,咱們須要去請求用戶權限。首先須要在 Info.plist 中配置" NSUserTrackingUsageDescription " 及描述文案,接着使用 AppTrackingTransparency 框架中的 ATTrackingManager 中的 requestTrackingAuthorizationWithCompletionHandler 請求用戶權限,在用戶受權後再去訪問 IDFA 纔可以獲取到正確信息。
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <AdSupport/AdSupport.h>
- (void)testIDFA {
if (@available(iOS 14, *)) {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
if (status == ATTrackingManagerAuthorizationStatusAuthorized) {
NSString *idfaString = [[ASIdentifierManager sharedManager] advertisingIdentifier].UUIDString;
}
}];
} else {
// 使用原方式訪問 IDFA
}
}
複製代碼
對於用戶拒絕受權 UserTracking 的狀況,能夠考慮接入蘋果的 SKAdNetwork 框架進行廣告分析。感興趣的同窗可進一步瞭解:developer.apple.com/documentati…
更加嚴格的隱私審覈,可讓用戶在下載 App 以前就知道此 App 將會須要哪些權限。目前蘋果商店要求全部應用在上架時都必須提供一份隱私政策。若是引入了第三方收集用戶信息等SDK,都須要向蘋果說明是這些信息的用途。
對於此次 iOS14 的隱私權限大升級和新嘗試,體現了蘋果對於用戶隱私的尊重。
從用戶角度來講,近年來愈來愈精準的廣告投放讓咱們愈來愈感受本身被」監視「着,這次升級後,咱們有了更多保護本身隱私的方式以及避免廣告騷擾的方法,蘋果此舉無疑會加大咱們對其的好感度和信任感。但從另外一個角度來講,對於 IDFA 的限制,可能會致使以前許多依靠廣告投放收入的免費 App 難以繼續維持生計,也可能也會致使免費 App 的數量有所下降。從開發者的角度來講,除了對 iOS14 隱私升級的積極適配外,也讓咱們感覺到了 iOS14 中對於用戶隱私的重視無疑會提升獲取用戶行爲信息的成本。
衝擊最大的應該就是廣告行業,對於目前的推薦算法和用戶拉新都會受到影響,如何在充分尊重用戶隱私的前提下進行廣告的精準投放對於開發者和廣告商來講都是一個不小的機遇和挑戰。
下一期,咱們聊聊 【Metal 新特性詳解|帶來的技術啓發和思考】,敬請持續關注~
參考資料
WWDC 2020 Apple Developer
Developer Documentation
手淘客戶端—小程序與跨平臺技術部
咱們是支撐小程序、小遊戲、Flutter 等跨平臺技術的核心團隊,有技術廣度和也有技術深度,咱們須要 iOS、Android、C++、Flutter、Canvas、遊戲引擎、WebGL 等各方面的人才。若是你善於學習,這是一個很好的接觸跨領域知識的機會。
若是你是個對技術有追求對小夥伴,請別猶豫,馬上聯繫我! 📮:lanya.sly@alibaba-inc.com