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
類型,如果需要監聽其他類型也可以簡單改造之。