tags:swift, macos
对剪贴板的支持是提高用户使用体验的一个重要因素。经常,我们的应用需要监听剪贴板的内容变化,并做出相应的反应。
在iOS上这个目的可以直接通过订阅 UIPasteboardChangedNotification
来完成,而在macOS上,苹果没有提供现成的 API。
不过,实现起来也不是很麻烦。我们可以写一个剪切板的监听器,实现这个目标。
监听器实现
import AppKit
class Clipboard {
typealias Hook = (String) -> Void
private let pasteboard = NSPasteboard.general
private let timerInterval = 1.0
private var changeCount: Int
private var hooks: [Hook]
init() {
changeCount = pasteboard.changeCount
hooks = []
}
func onNewCopy(_ hook: @escaping Hook) {
hooks.append(hook)
}
func startListening() {
Timer.scheduledTimer(timeInterval: timerInterval,
target: self,
selector: #selector(checkForChangesInPasteboard),
userInfo: nil,
repeats: true)
}
func copy(_ string: String) {
pasteboard.declareTypes([NSPasteboard.PasteboardType.string], owner: nil)
pasteboard.setString(string, forType: NSPasteboard.PasteboardType.string)
}
@objc
func checkForChangesInPasteboard() {
guard pasteboard.changeCount != changeCount else {
return
}
if let lastItem = pasteboard.string(forType: NSPasteboard.PasteboardType.string) {
for hook in hooks {
hook(lastItem)
}
}
changeCount = pasteboard.changeCount
}
}
使用
需要在应用启动的时候创建监听器,并启动之。可以在appdelegate中完成:
class AppDelegate: NSObject, NSApplicationDelegate {
let clipboard = Clipboard()
func applicationDidFinishLaunching(_ aNotification: Notification) {
clipboard.startListening()
clipboard.onNewCopy { (content) in
print(content)
}
}
这样只要用户复制了文本到剪切板中, onNewCopy
就会自动触发,打印出复制的内容了。
以上的实现只监听了String
类型,如果需要监听其他类型也可以简单改造之。
网友评论