如何查看"Copied text is from which Application"?

How to check "Copied text is from which Application"?

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

没有 API 检索负责将数据放到粘贴板上的应用程序。

如果您想了解的是您自己的应用程序,那么您必须自己处理,否则您就不走运了。

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

虽然没有API,但还是有办法的。这有点像 hack,但 Apple 在他们的示例中就是这样做的,所以我想没关系。

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

这是一个 class 执行此操作的示例:

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()

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