在 iOS 14 之前,任何应用都可以随意读写粘贴板数据,但这很不安全,因为我们每天都会复制大量信息,也包含密码、银行帐户等敏感信息,如果不加干涉,这些信息很容易被泄漏出去。
从 iOS 14 中,当有 App 访问剪切板的时候,手机顶部会弹出一个提示,xxx 访问了剪切板。通过这个提示让我们知道谁在访问我们的剪切板。

但这种方案并没有解决剪切板的数据可能被泄漏的问题,因为即使用户知道某个应用程序正在读取粘贴板,他们也不能禁止。
在 iOS 16 中,苹果制定了一个新的用户权限,即 App 访问剪切板时,必须先经过用户的允许,如果用户点击拒绝,则这个 App 将不能访问到剪切板内容。

默认情况下,App 每次访问剪切板都会弹出这个权限询问弹窗(即使某一次你点了允许或拒绝),那作为用户怎么一次性设定某个 App 允许或者拒绝呢?可以打开系统设置,下拉找到这个 App,比如淘宝,点开之后会出现权限列表,页面底部会有一个从其他 App 粘贴的选项,点进去之后,可以为这个 App 设置永久的粘贴板访问权限。


作为开发者,如果 App 每次都弹这个权限弹窗,其实是非常打扰用户的,如何在没有权限的情况下访问剪切板数据呢?
原则上来说,仅当 App 尝试在没有用户意图的情况下访问粘贴板数据时,苹果才不会显示对话框(比如电商 App 会在启动的时候就访问剪切板,看看有没有复制过商品信息)。那要避免这个权限弹窗,就要避免直接访问 UIPasteboard.general.string。
有几种方法可以避免此提示出现在您的应用中
1. 引导用户给权限,可以出一些友好的提示,让用户到设置中启用从其他 App 粘贴的权限,这样以后就不会再弹权限弹窗了
2. 用户主动在输入框中操作复制/粘贴
用户长按输入框 UITextField/UITextView 等,在系统弹窗面板中粘贴

3. 用户使用键盘快捷方式 (Command+V) 粘贴到硬件键盘上
4. 用户使用键盘上的快捷粘贴方式,比如验证码

5. 使用 iOS 16 的新组件,UIPasteControl[1]
这个组件会渲染出一个按钮,按钮需要绑定一个输入框,当用户点击按钮时,复制的内容会粘贴到这个输入框中,示例代码如下
let textView = UITextView(frame: view.bounds)
view.addSubview(textView)
let configuration = UIPasteControl.Configuration()
configuration.baseBackgroundColor = .red
configuration.baseForegroundColor = .magenta
configuration.cornerStyle = .capsule
configuration.displayMode = .iconAndLabel
let pasteButton = UIPasteControl(configuration: configuration)
pasteButton.frame = CGRect(x: view.bounds.width/2.0, y: view.bounds.height/2.0, width: 150, height: 60)
textView.addSubview(pasteButton)
pasteButton.target = textView
UIPasteControl 按钮的一些样式

参考资料
[1]
UIPasteControl 官方文档: developer.apple.com/documentati…
本文同步自微信公众号 “iOS新知”,每天准时分享一个新知识,快来关注我吧!