swift - 如何检查 "Copied text is from which Application"?

标签 swift cocoa nsapplication nspasteboard

最近,我正在开发一个基于Pasteboard的应用程序。我想知道复制的文本没有存储在所选正在运行的应用程序的粘贴板中。有人有想法吗?

最佳答案

虽然你的问题有点不清楚,但我的理解是你想知道哪个应用程序刚刚向粘贴板添加了一些东西(当然你也想要粘贴板的内容)。

虽然没有 API,但有办法。这是一种 hack,但 Apple 在他们的示例中就是这样做的,所以我想这没问题。

主要思想是用计时器定期轮询粘贴板,并同时观察.NSWorkspaceDidActivateApplication:这样当粘贴板中出现新内容时,我们就可以知道哪个应用程序处于事件状态。

下面是执行此操作的类的示例:

class PasteboardWatcher {

    private let pasteboard = NSPasteboard.general()

    // Keep track of the changes in the pasteboard.
    private var changeCount: Int

    // Used to regularly poll the pasteboard for changes.
    private var timer: Timer?

    private var frontmostApp: (name: String, bundle: String)?

    init() {
        // On launch, we mirror the pasteboard context.
        self.changeCount = pasteboard.changeCount

        // Registers if any application becomes active (or comes frontmost) and calls a method if it's the case.
        NSWorkspace.shared().notificationCenter.addObserver(self, selector: #selector(activeApp(sender:)), name: .NSWorkspaceDidActivateApplication, object: nil)

        if let types = pasteboard.types {
            print("Available pasteboards: \(types)")
        }
    }

    // Start polling for changes in pasteboard.
    func startPolling() {
        self.timer = Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(checkForChangesInPasteboard), userInfo: nil, repeats: true)
    }

    // Called by NSWorkspace when any application becomes active or comes frontmost.
    @objc private func activeApp(sender: NSNotification) {
        if let info = sender.userInfo,
            let content = info[NSWorkspaceApplicationKey] as? NSRunningApplication,
            let name = content.localizedName,
            let bundle = content.bundleIdentifier
        {
            frontmostApp = (name: name, bundle: bundle)
        }
    }

    @objc private func checkForChangesInPasteboard() {
        if pasteboard.changeCount != changeCount {
            changeCount = pasteboard.changeCount
            if let copied = pasteboard.string(forType: NSStringPboardType),
                let app = frontmostApp
            {
                print("Copied string is: '\(copied)' from \(app.name) (\(app.bundle))")
            }
        }
    }

}

像这样简单地使用它:

let watcher = PasteboardWatcher()
watcher.startPolling()

它会在控制台中打印复制的字符串,以及应用程序的名称和包。

关于swift - 如何检查 "Copied text is from which Application"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49398954/

相关文章:

swift - 检查一个 NSRange 是否在另一个 NSRange 内或与它快速相交?

macos - CFBundleCopyExecutableURL 不返回绝对 URL

objective-c - distanceFilter 属性使用

macos - 为什么 NSApplication sharedApplication mainMenu 返回 nil ?

objective-c - 如何使状态栏应用程序与其他状态栏应用程序一起捕获 'applicationDidResignActive:'?

swift - 成员 'CBC' 不带参数

swift - AKAmplitudeTracker振幅使用audioKit获得0.0

objective-c - NSDictionary 计算所有子项的数量

swift - 在 Swift 中将 replyToApplicationShouldTerminate 发送到 NSApplication

ios - 默认情况下在 collectionView 中滚动时选择单元格