在 iOS 14 開發(fā)者預(yù)覽版發(fā)布后,第一時間下載嘗鮮了,最大的變化就是 app 訪問剪貼板在頂部有一個提示:

pasted from anothor device / pasted from xxx
怎么觸發(fā)的
出于好奇這個檢測是怎么觸發(fā)的,通過一步步 debug 最發(fā)現(xiàn)在(一開始還分析錯了,感謝頁面仔指正):
-[PBServerConnection requestItemFromPasteboardWithName:UUID:authenticationMessage:itemIndex:typeIdentifier:completionBlock:] 這個方法,偽代碼如下:
NSXPCConnection *xpcConnection = [self serverConnection];
void (^loggingErrorHandler)(NSError *) = _loggingErrorHandler;
__NSXPCInterfaceProxy_PBClientToServerProtocol *proxy = [xpcConnection remoteObjectProxyWithErrorHandler:loggingErrorHandler];
[proxy requestItemFromPasteboardWithName:UUID:authenticationMessage:itemIndex:typeIdentifier:completionBlock:
... callback
]
一旦執(zhí)行 proxy 的 request 方法,就使用 XPC 發(fā)送消息,將請求參數(shù)和回調(diào)一起發(fā)送到系統(tǒng)的 pasteboard 進(jìn)程來請求數(shù)據(jù),當(dāng)檢測如果你粘貼的數(shù)據(jù)不是來源你的 app 就會彈出提示,由于這個校驗和提醒的邏輯并不在 app 進(jìn)程內(nèi),在應(yīng)用層是沒有辦法繞過檢測拿到數(shù)據(jù)的,apple 還是很嚴(yán)謹(jǐn)?shù)摹?/p>
如何查看是哪個方法導(dǎo)致了提示
Xcode 打一個符號斷點-[PBServerConnection requestItemFromPasteboardWithName:UUID:authenticationMessage:itemIndex:typeIdentifier:completionBlock:] 當(dāng)然了如果你嫌太長,下面這個也可以:
-[PBItemRepresentation _loadCompletionBlock:]
如何減少彈提示
盡量減少 Direct access 的方法調(diào)用,這類方法在 UIPasteboard.h 有列出來,比如
[[UIPasteboard generalPasteboard] items]
、[[UIPasteboard generalPasteboard] itestringss],可以先用 Queries 的方法做一些判,比如[[UIPasteboard generalPasteboard] hasStrings],另外如果有頻繁訪問剪貼板的需求,最好監(jiān)聽UIPasteboardChangedNotification通知,在剪貼板發(fā)生改變才去讀取。iOS 14 提供了新的 API 用來檢測特定類型的剪貼板數(shù)據(jù):
- (void)detectValuesForPatterns:(NSSet<UIPasteboardDetectionPattern> *)patterns
completionHandler:(void(^)(NSDictionary<UIPasteboardDetectionPattern, id> * _Nullable,
NSError * _Nullable))completionHandler
不過目前的類型只有 2 個,而且不能自定義 Pattern:
UIPasteboardDetectionPatternProbableWebURL 用于檢測剪貼板的 URL 數(shù)據(jù)
UIPasteboardDetectionPatternProbableWebSearch 用于檢測剪貼板可能為搜索關(guān)鍵詞的數(shù)據(jù)
比如你是一個瀏覽器應(yīng)用,在用戶激活地址輸入框的時候,你就可以用 UIPasteboardDetectionPatternProbableWebURL 來訪問剪貼板讀取為 URL 的數(shù)據(jù),如果此時沒有 URL 也不會彈框提醒,這樣可以避免每次直接讀剪貼板而導(dǎo)致頻繁彈框。
既然有這個特性,那么 H5 利用剪貼板來傳遞數(shù)據(jù),也可以改成 URL 的形式,把要傳遞的內(nèi)容放在 URL 的參數(shù)里,這樣 app 可以檢測到有 URL 類型才真正訪問剪貼板讀取 URL 并解析出內(nèi)容。
3.通過 pasteboardWithName:create: 實例化的剪貼板數(shù)據(jù)訪問是不會觸發(fā)彈框提醒的,所以應(yīng)用間的數(shù)據(jù)傳遞暫時不受影響(很多 SDK 都是這么干的)