47

Apple のPasteboard Programming Guideを読みましたが、特定の質問に対する回答がありません。

一般的なペーストボードに書き込まれたすべてのものを追跡する Cocoa アプリケーション (iOS ではなく OS X 用) を作成しようとしています (そのため、アプリケーションがコピーして貼り付けたときはいつでも、ドラッグ アンド ドロップではありません)。 、これも NSPasteboard を利用します)。基本的にバックグラウンドスレッドで一般的なペーストボードを常にポーリングし、 changeCountをチェックすることで、これを (ほぼ) 達成できました。もちろん、これを行うと、私は内部で非常に汚れた気分になります.

私の質問は、一般的なペーストボードに変更が加えられるたびに、何らかのコールバックを通じて私に通知するようにペーストボード サーバーに依頼する方法はありますか? NSPasteboard クラス リファレンスには何も見つかりませんでしたが、どこかに潜んでいることを願っています。

これを実現するもう 1 つの方法は、一般的なペーストボードの実装を、NSPasteboard のサブクラスと交換して、コールバックを発行するように自分で定義できる方法がある場合です。たぶん、このようなことが可能ですか?

これが App Store に準拠した公開 API で可能であれば非常に望ましいですが、非公開 API を使用する必要がある場合は、それも採用します。

ありがとう!

4

6 に答える 6

13

かつて、通知 API に対する決定が記述されたメーリング リストに投稿がありました。いまいち見つからないけど。肝心なのは、実際にはその必要がないにもかかわらず、おそらくあまりにも多くのアプリケーションがその API に登録するということです。次に何かをコピーすると、システム全体が狂ったように新しいクリップボードのコンテンツを通過し、コンピューターに多くの作業が発生します。だから私は彼らがすぐにその行動を変えるとは思わない. NSPasteboard API 全体も、changeCount を使用して内部的に構築されています。したがって、NSPasteboard のカスタム サブクラスでさえ、ポーリングを継続する必要があります。

ペーストボードが変更されたかどうかを本当に確認したい場合は、changeCount を 0.5 秒観察し続けてください。整数の比較は非常に高速であるため、パフォーマンスの問題はありません。

于 2012-04-07T11:03:12.297 に答える
1

投票する必要はありません。通常、ペーストボードは、現在のビューが非アクティブであるか、フォーカスがない場合にのみ変更されます。ペーストボードには、コンテンツが変更されるとインクリメントされるカウンターがあります。ウィンドウがフォーカスを取り戻すと (windowDidBecomeKey)、changeCount が変更されたかどうかを確認し、それに応じて処理します。

これはすべての変更をキャプチャするわけではありませんが、ペーストボードがアクティブになったときに異なる場合にアプリケーションが応答できるようにします。

スイフトで...

var pasteboardChangeCount = NSPasteboard.general().changeCount
func windowDidBecomeKey(_ notification: Notification)
{   Swift.print("windowDidBecomeKey")
    if  pasteboardChangeCount != NSPasteboard.general().changeCount
    {   viewController.checkPasteboard()
        pasteboardChangeCount  = NSPasteboard.general().changeCount
    }
}
于 2017-07-31T02:00:06.540 に答える
0

Swift 5 で非常に単純化されたバージョンが必要な場合は、それが機能します (@Devarshi コードに基づく):

    func WatchPasteboard(copied: @escaping (_ copiedString:String) -> Void) {
        let pasteboard = NSPasteboard.general
        var changeCount = NSPasteboard.general.changeCount
        Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
            if let copiedString = pasteboard.string(forType: .string) {
                if pasteboard.changeCount != changeCount {        
                    copied(copiedString)                
                    changeCount = pasteboard.changeCount
                }
            }
        }
    }

使い方・使い方は以下の通りです。

WatchPasteboard {
    print("copy detected : \($0)")
}

以下のように出力されます。

watched : pasteboard1
watched : pasteboard2
于 2020-02-16T14:17:28.373 に答える