在 iOS 14 開發(fā)者預(yù)覽版發(fā)布后哲银,第一時(shí)間下載嘗鮮了莱没,最大的變化就是 app 訪問(wèn)剪貼板在頂部有一個(gè)提示:
pasted from anothor device / pasted from xxx
怎么觸發(fā)的
出于好奇這個(gè)檢測(cè)是怎么觸發(fā)的掠剑,通過(guò)一步步 debug 最發(fā)現(xiàn)在(一開始還分析錯(cuò)了,感謝頁(yè)面仔指正):
-[PBServerConnection requestItemFromPasteboardWithName:UUID:authenticationMessage:itemIndex:typeIdentifier:completionBlock:]
這個(gè)方法郊愧,偽代碼如下:
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ā)送消息井佑,將請(qǐng)求參數(shù)和回調(diào)一起發(fā)送到系統(tǒng)的 pasteboard 進(jìn)程來(lái)請(qǐng)求數(shù)據(jù)属铁,當(dāng)檢測(cè)如果你粘貼的數(shù)據(jù)不是來(lái)源你的 app 就會(huì)彈出提示,由于這個(gè)校驗(yàn)和提醒的邏輯并不在 app 進(jìn)程內(nèi)躬翁,在應(yīng)用層是沒(méi)有辦法繞過(guò)檢測(cè)拿到數(shù)據(jù)的焦蘑,apple 還是很嚴(yán)謹(jǐn)?shù)摹?/p>
如何查看是哪個(gè)方法導(dǎo)致了提示
Xcode 打一個(gè)符號(hào)斷點(diǎn)-[PBServerConnection requestItemFromPasteboardWithName:UUID:authenticationMessage:itemIndex:typeIdentifier:completionBlock:]
當(dāng)然了如果你嫌太長(zhǎng),下面這個(gè)也可以:
-[PBItemRepresentation _loadCompletionBlock:]
如何減少?gòu)椞崾?/h3>
盡量減少 Direct access 的方法調(diào)用盒发,這類方法在 UIPasteboard.h 有列出來(lái)例嘱,比如 [[UIPasteboard generalPasteboard] items]
、[[UIPasteboard generalPasteboard] itestringss]
宁舰,可以先用 Queries 的方法做一些判拼卵,比如 [[UIPasteboard generalPasteboard] hasStrings]
,另外如果有頻繁訪問(wèn)剪貼板的需求蛮艰,最好監(jiān)聽 UIPasteboardChangedNotification
通知腋腮,在剪貼板發(fā)生改變才去讀取。
iOS 14 提供了新的 API 用來(lái)檢測(cè)特定類型的剪貼板數(shù)據(jù):
- (void)detectValuesForPatterns:(NSSet<UIPasteboardDetectionPattern> *)patterns
completionHandler:(void(^)(NSDictionary<UIPasteboardDetectionPattern, id> * _Nullable,
NSError * _Nullable))completionHandler
盡量減少 Direct access 的方法調(diào)用盒发,這類方法在 UIPasteboard.h 有列出來(lái)例嘱,比如 [[UIPasteboard generalPasteboard] items]
、[[UIPasteboard generalPasteboard] itestringss]
宁舰,可以先用 Queries 的方法做一些判拼卵,比如 [[UIPasteboard generalPasteboard] hasStrings]
,另外如果有頻繁訪問(wèn)剪貼板的需求蛮艰,最好監(jiān)聽 UIPasteboardChangedNotification
通知腋腮,在剪貼板發(fā)生改變才去讀取。
iOS 14 提供了新的 API 用來(lái)檢測(cè)特定類型的剪貼板數(shù)據(jù):
- (void)detectValuesForPatterns:(NSSet<UIPasteboardDetectionPattern> *)patterns
completionHandler:(void(^)(NSDictionary<UIPasteboardDetectionPattern, id> * _Nullable,
NSError * _Nullable))completionHandler
不過(guò)目前的類型只有 2 個(gè)壤蚜,而且不能自定義 Pattern:
UIPasteboardDetectionPatternProbableWebURL
用于檢測(cè)剪貼板的 URL 數(shù)據(jù)
UIPasteboardDetectionPatternProbableWebSearch
用于檢測(cè)剪貼板可能為搜索關(guān)鍵詞的數(shù)據(jù)
比如你是一個(gè)瀏覽器應(yīng)用,在用戶激活地址輸入框的時(shí)候,你就可以用 UIPasteboardDetectionPatternProbableWebURL
來(lái)訪問(wèn)剪貼板讀取為 URL 的數(shù)據(jù)即寡,如果此時(shí)沒(méi)有 URL 也不會(huì)彈框提醒,這樣可以避免每次直接讀剪貼板而導(dǎo)致頻繁彈框。
既然有這個(gè)特性袜刷,那么 H5 利用剪貼板來(lái)傳遞數(shù)據(jù)聪富,也可以改成 URL 的形式,把要傳遞的內(nèi)容放在 URL 的參數(shù)里著蟹,這樣 app 可以檢測(cè)到有 URL 類型才真正訪問(wèn)剪貼板讀取 URL 并解析出內(nèi)容墩蔓。
3.通過(guò) pasteboardWithName:create: 實(shí)例化的剪貼板數(shù)據(jù)訪問(wèn)是不會(huì)觸發(fā)彈框提醒的梢莽,所以應(yīng)用間的數(shù)據(jù)傳遞暫時(shí)不受影響(很多 SDK 都是這么干的)