背景
Apple從iOS14后,增加了對剪貼板內(nèi)容的隱私保護
131217723881.jpeg
iOS16的剪貼板彈窗。
936be07d1526176.jpg
問題
雖然用戶的隱私被更好的保護了,但用戶體驗也在下降。
在iOS16中,只要讀取了[UIPasteboard generalPasteboard].string
就會彈出是否允許的彈窗,且彈窗沒有暴露api來控制,也沒有記錄上次的點擊結(jié)果。如果拒絕,下次讀取還是會彈出。
解決方案
針對剪貼版的問題。有兩種解決方案
1.用戶主動讀取剪貼板
使用iOS16 UIKit的新組件 UIPasteControl,來讀取剪貼板內(nèi)容,則不會觸發(fā)彈窗
用法
- 初始化pasteControl
@interface ViewController ()
@property (nonatomic, strong) UIPasteControl *pasteControl;
@end
@implementation ViewController
- (void)viewDidLoad {
self.control = [[TestPasteControl alloc] init];
self.control.target = self;
[self.view addSubview:self.control];
self.control.frame = CGRectMake(0, 0, 100, 100);
}
- 配置configuration(支持類型)
- (void)viewDidLoad {
// ...
self.pasteConfiguration = [[UIPasteConfiguration alloc] initWithTypeIdentifiersForAcceptingClass:[NSString class]];
}
3.target重寫pasteItemProviders:itemProviders方法,用于監(jiān)聽pasteControl點擊后的回調(diào)
- (void)pasteItemProviders:(NSArray<NSItemProvider *> *)itemProviders {
for (NSItemProvider *provider in itemProviders) {
[provider loadObjectOfClass:NSString.class
completionHandler:^(id<NSItemProviderReading> _Nullable object, NSError * _Nullable error) {
if (object) {
dispatch_async(dispatch_get_main_queue(), ^{
NSString *result = [NSString stringWithFormat:@"復制的內(nèi)容: %@", object];
NSLog(@"%@",result);
});
}
}];
}
}
2.用戶無感知讀取
如淘寶分享商品,雖然不能避免觸發(fā)讀取剪貼板的彈窗,但可以利用一些不會觸發(fā)彈窗的,判斷內(nèi)容的api。來減少彈窗出現(xiàn)的概率,增大讀取準確內(nèi)容的命中率。
用法
使用iOS14新增的api
detectPatternsForPatterns:completionHandler:
detectPatternsForPatterns:inItemSet:completionHandler:
來提前判斷
可以判斷的類型
typedef NSString * UIPasteboardDetectionPattern NS_TYPED_ENUM API_AVAILABLE(ios(14.0));
/// NSString value, suitable for implementing "Paste and Go"
UIKIT_EXTERN UIPasteboardDetectionPattern const UIPasteboardDetectionPatternProbableWebURL API_AVAILABLE(ios(14.0));
/// NSString value, suitable for implementing "Paste and Search"
UIKIT_EXTERN UIPasteboardDetectionPattern const UIPasteboardDetectionPatternProbableWebSearch API_AVAILABLE(ios(14.0));
/// NSNumber value
UIKIT_EXTERN UIPasteboardDetectionPattern const UIPasteboardDetectionPatternNumber API_AVAILABLE(ios(14.0));
/// Array of DDMatchLink values
UIKIT_EXTERN UIPasteboardDetectionPattern const UIPasteboardDetectionPatternLink NS_REFINED_FOR_SWIFT API_AVAILABLE(ios(15.0));
/// Array of DDMatchPhoneNumber values
UIKIT_EXTERN UIPasteboardDetectionPattern const UIPasteboardDetectionPatternPhoneNumber NS_REFINED_FOR_SWIFT API_AVAILABLE(ios(15.0));
/// Array of DDMatchEmailAddress values
UIKIT_EXTERN UIPasteboardDetectionPattern const UIPasteboardDetectionPatternEmailAddress NS_REFINED_FOR_SWIFT API_AVAILABLE(ios(15.0));
/// Array of DDMatchAddress values
UIKIT_EXTERN UIPasteboardDetectionPattern const UIPasteboardDetectionPatternPostalAddress NS_REFINED_FOR_SWIFT API_AVAILABLE(ios(15.0));
/// Array of DDMatchCalendarEvent values
UIKIT_EXTERN UIPasteboardDetectionPattern const UIPasteboardDetectionPatternCalendarEvent NS_REFINED_FOR_SWIFT API_AVAILABLE(ios(15.0));
/// Array of DDMatchShipmentTrackingNumber values
UIKIT_EXTERN UIPasteboardDetectionPattern const UIPasteboardDetectionPatternShipmentTrackingNumber NS_REFINED_FOR_SWIFT API_AVAILABLE(ios(15.0));
/// Array of DDMatchFlightNumber values
UIKIT_EXTERN UIPasteboardDetectionPattern const UIPasteboardDetectionPatternFlightNumber NS_REFINED_FOR_SWIFT API_AVAILABLE(ios(15.0));
/// Array of DDMatchMoneyAmount values
UIKIT_EXTERN UIPasteboardDetectionPattern const UIPasteboardDetectionPatternMoneyAmount NS_REFINED_FOR_SWIFT API_AVAILABLE(ios(15.0));
判斷邏輯
UIPasteboard *board = [UIPasteboard generalPasteboard];
[board detectPatternsForPatterns:[NSSet setWithObjects:UIPasteboardDetectionPatternProbableWebURL, UIPasteboardDetectionPatternNumber, UIPasteboardDetectionPatternProbableWebSearch, nil]
completionHandler:^(NSSet<UIPasteboardDetectionPattern> * _Nullable set, NSError * _Nullable error) {
for (NSString *type in set) {
if ([type isEqualToString:UIPasteboardDetectionPatternProbableWebURL]) {
//do something
}
}
}];
總結(jié)
Apple一直是一家重視用戶隱私的企業(yè),但這次iOS16關(guān)于剪貼板的更新,蘋果自己的設(shè)計師也覺得有些過量,目前的解決方案也是盡量提高下用戶體驗。下個版本iOS16.1不知道是否有更優(yōu)雅的解決方式。后續(xù)如果有需要也可以更新一下swift的實現(xiàn)。大家有更好的方案也可以一起討論。