iOS14剪下板探究,淘寶實現方法分析

再問天發表於2020-09-27

隨著iOS 14的釋出,剪下板的濫用也被大家所知曉。只要是APP讀取剪下板內容,系統都會在頂部彈出提醒,而且這個提醒不能夠關閉。這樣,大家在使用APP的過程中就能夠看到哪些APP使用了剪下板。

正好我們自己的應用也使用了剪下板,升級了iOS 14之後彈的著實讓人心煩。就想著怎麼處理一下,翻了一下UIPasteboard的文件,發現相關的內容並不多。
讀取UIPasteboardstringstringsURLURLsimageimagescolorcolors的時候會觸發系統提示。
使用hasStringshasURLshasImageshasColors等方法的時候不會觸發系統提示。
那麼思路就是儘可能少的去呼叫會觸發系統提示的方法,根據其他方法去判斷確實需要讀取的時候再去呼叫那些方法。
根據我們自己的情況,只有判斷hasStringsYES就去讀取,又不能清剪下板,其實還是有點不盡人意,然後又看到這個屬性:

@property(readonly, nonatomic) NSInteger changeCount;
The number of times the pasteboard’s contents have changed.

Whenever the contents of a pasteboard changes—specifically, when pasteboard items are added, modified, or removed—UIPasteboard increments the value of this property. After it increments the change count, UIPasteboard posts the notifications named UIPasteboardChangedNotification (for additions and modifications) and UIPasteboardRemovedNotification (for removals). These notifications include (in the userInfo dictionary) the types of the pasteboard items added or removed. Because UIPasteboard waits until the end of the current event loop before incrementing the change count, notifications can be batched. The class also updates the change count when an app reactivates and another app has changed the pasteboard contents. When users restart a device, the change count is reset to zero.

然後就又加了一個條件,記錄一下真正讀取剪下板時的changeCount,如果下次讀取的時候沒有發生變化則不讀取。
這樣一來效果就好多了,應用執行生命週期內,基本上只會彈出一次提示。

但是,後來看到淘寶更牛逼,命中了真正分享出來的內容才會彈,其他則不會彈。然後就研究了一下淘寶的分享內容和新的API文件,大概得到了答案。
先看下淘寶的分享內容:

9?幅治內容 Http:/T$AJg8c4IfW3q$開啟?綯..寶?【貴州茅臺酒 茅臺 飛天53度醬香型白酒收藏 500ml*1單瓶裝送禮高度】

組成部分:數字+文字+連結的形勢,再結合iOS 14提供的新API:

detectPatternsForPatterns:completionHandler:
detectPatternsForPatterns:inItemSet:completionHandler:                                

UIPasteboardDetectionPattern系統只提供了三種:

  1. 數字 UIPasteboardDetectionPatternNumber
  2. 連結 UIPasteboardDetectionPatternProbableWebURL
  3. 搜尋UIPasteboardDetectionPatternProbableWebSearch

大膽猜測,淘寶應該是通過判斷是否符合數字和連結的規則來判斷是否命中分享內容。

然後就寫了一個demo來驗證,核心程式碼如下:

UIPasteboard *board = [UIPasteboard generalPasteboard];
    
[board detectPatternsForPatterns:[NSSet setWithObjects:UIPasteboardDetectionPatternProbableWebURL, UIPasteboardDetectionPatternNumber, UIPasteboardDetectionPatternProbableWebSearch, nil]
                   completionHandler:^(NSSet<UIPasteboardDetectionPattern> * _Nullable set, NSError * _Nullable error) {
        
        BOOL hasNumber = NO, hasURL = NO;
        for (NSString *type in set) {
            if ([type isEqualToString:UIPasteboardDetectionPatternProbableWebURL]) {
                hasURL = YES;
            } else if ([type isEqualToString:UIPasteboardDetectionPatternNumber]) {
                hasNumber = YES;
            }
        }
        
        if (hasNumber && hasURL) {
            
            dispatch_async(dispatch_get_main_queue(), ^{
                UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"溫馨提示" message:[NSString stringWithFormat:@"%@\n%@", [board string], @"符合淘寶的讀取標準"] preferredStyle:UIAlertControllerStyleAlert];
                UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleCancel handler:nil];
                [alert addAction:cancelAction];
                [self presentViewController:alert animated:YES completion:nil];
            });
        }
    }];

然後構造了一個看起來符合條件1 http:/123abc的串去反向驗證了一下發現demo和淘寶的結果的表現是一致的,都彈了系統提示。

具體的demo可去github下載。

原地址:https://y500.me/2020/09/27/ios14_taobao_uipasteboard/

相關文章