iOS小技能:iOS14 讀取用户剪切板數據彈出提示的兼容方案

語言: CN / TW / HK

持續創作,加速成長!這是我參與「掘金日新計劃 · 10 月更文挑戰」的第12天,點擊查看活動詳情

前言

背景:在iOS14中,如果APP讀取剪切版的內容時,手機會彈出提示,提示哪個APP在獲取剪切板內容。

讀取UIPasteboardstringstringsURLURLsimageimagescolorcolors的時候會觸發系統提示。 使用hasStringshasURLshasImageshasColors等方法的時候不會觸發系統提示。

  • 讀取剪貼板的代碼 在這裏插入圖片描述

像這種第三方SDK,及時聯繫對應的SDK開發者。比如極光的v3.3.6就及時進行了適配

在這裏插入圖片描述

在這裏插入圖片描述

劃重點

  • 先判斷剪切板內容的各式,如果符合規則才讀取剪切板
  • 查找哪些SDK使用了剪切板,及時升級SDK。

比如發現了JCore SDK在iOS 14引用剪貼板,該行為導致APP被用户懷疑隱私泄露,請予以重視

I、彈出提示的兼容方案:儘可能少的去調用會觸發系統提示的方法

彈出提示的原因:使用 UIPasteboard 訪問用户數據

方案一:先判斷剪切板內容的各式,如果符合規則採取讀取。

例如app讀取口令時判斷是否符合數字和鏈接的規則

iOS14 剪切板適配案例分析:讀取口令的實現方法

http://kunnan.blog.csdn.net/article/details/108894751

方案二:使用changeCount來記錄剪切板的數據是否發生變化

1.1 先判斷剪切板內容的各式,如果符合規則才讀取剪切板(例如淘寶的淘口令)

如果應用僅僅訪問只訪問URL格式的剪切板內容,或者特定規則的內容,比如淘口令,就可以使用API先判斷,確實是符合規則的時候再去讀取

判斷是否為URL格式: UIPasteboardDetectionPatternAPI

``` 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)); ```

下面 API 可以獲得具體的 URL 信息,但是會觸發剪切板提示。並且實測當用户剪切板中包含多個 URL 時只會返回第一個。

``` // Detection

/// Detects patterns in the first pasteboard item. /// /// @param patterns Detect only these patterns. /// @param completionHandler Receives which patterns were detected, or an error. - (void)detectPatternsForPatterns:(NSSet )patterns                 completionHandler:(void(^)(NSSet * _Nullable,                                            NSError * _Nullable))completionHandler NS_REFINED_FOR_SWIFT API_AVAILABLE(ios(14.0));              /// Detects patterns in the specified pasteboard items. /// /// @param patterns Detect only these patterns. /// @param itemSet Specifies which pasteboard items by their position. Nil means all items. /// @param completionHandler Receives which patterns were detected per item specified, ///                          or an error. - (void)detectPatternsForPatterns:(NSSet )patterns                         inItemSet:(NSIndexSet * _Nullable)itemSet                 completionHandler:(void(^)(NSArray *> * _Nullable,                                            NSError * _Nullable))completionHandler NS_REFINED_FOR_SWIFT API_AVAILABLE(ios(14.0));                   ```

  • 例子

``` NSSet *patterns = [[NSSet alloc] initWithObjects:UIPasteboardDetectionPatternProbableWebURL, nil];

[[UIPasteboard generalPasteboard] detectPatternsForPatterns:patterns completionHandler:^(NSSet * _Nullable result, NSError * _Nullable error) {     if (result && result.count) {             // 當前剪切板中存在 URL                 } }]; ```

1.2 使用changeCount來記錄剪切板的數據是否發生變化


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

II 、 查找哪些SDK使用了剪切板

app出現了從後台喚起會彈出 讀取剪切板的 提示,安全部門要求要趕緊查,全局搜索了code,發現並沒有讀取剪切板的代碼,比竇娥還冤,只能是第三方SDK的了,

2.1 Symbolic breakpoint 進行查找


  • 用Xcode的Symbolic breakpoint,調試[UIPasteboard generalPasteboard]

在這裏插入圖片描述 在這裏插入圖片描述

使用例子:

  • 從後台喚起app會有這個提示
  • 單步向下走幾步,然後就會出現調用方

在這裏插入圖片描述

在這裏插入圖片描述

立馬發現了JCore iOS SDK在iOS 14引用剪貼板該行為會導致APP被用户懷疑隱私泄露,請予以重視

升級新版進行適配 iOS 14。

pod 'JPush' , '3.3.6'

2.2 使用命令行查找哪些SDK使用了剪切板

  • grep -r "UIPasteboard" . 在這裏插入圖片描述

➜  retail git:(develop) grep -r "UIPasteboard" . ./retail/other/tool/CopyTextLabel/QCTCopyTextLabel.m:    UIPasteboard * paste = [UIPasteboard generalPasteboard]; ./retail/class/business/Merchant_self_recording開户申請/oldNewAddStores/NewAddStores/QCTCopyLabel.m:    UIPasteboard * paste = [UIPasteboard generalPasteboard]; ./retail/class/business/Merchant_self_recording開户申請/oldNewAddStores/NewAddStores/QCTStoresDetailViewController.m:    [UIPasteboard generalPasteboard].string = titleLab.text ? titleLab.text : @""; Binary file ./Pods/JCore/libjcore-ios-2.3.2.a matches ./Pods/QMUIKit/QMUIKit/QMUIComponents/QMUILabel.m:        UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; Binary file ./Pods/JPush/libjpush-ios-3.3.4.a matches

  • find . -type f | grep -e ".framework" | xargs grep -s UIPasteboard

```

➜  Housekeeper git:(develop) find . -type f | grep -e ".framework" | xargs grep -s UIPasteboard

Binary file ./Housekeeper/other/extension/iOS/thirdparties/thirdparties_ios_1.0.5/UTDID.framework/Versions/A/UTDID matches Binary file ./Housekeeper/other/extension/iOS/common/common_ios_2.1.1/normal/UMCommon.framework/Versions/A/UMCommon matches ```

  • find . -type f | grep -e ".a" | xargs grep -s AUPasteboard

III 、例子:升級JPush SDK

pod 'JPush' , '3.3.6'

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

IV、 see also

在這裏插入圖片描述

在這裏插入圖片描述

4.1 升級CocoaPods(適配Xcode12)

  • 升級採用gem即可,命令如下

sudo gem install cocoapods

發現版本1.9.1 與Xcode12 不是很匹配,於是就升級新版本看下。

➜  Housekeeper git:(develop) pod --version 1.9.1

如果沒升級,主要問題是,如果採用pod install --verbose --no-repo-update 之後,Xcode的編譯設置不會 自動修改other Linker Flags

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

升級到1.9.3 再次升級SDK的時候,就適配Xcode12,可以自動修改other Linker Flags參數了

在這裏插入圖片描述

在這裏插入圖片描述

因此升級Xcode的時候,最好也同時升級下CocoaPods