Receive notifications when something is added to NSPasteboard

In my application, I want to be notified if something is added to the NSPasteboard. If I copy text from any other program, I want my application to know about it.

Somewhere I read that this is impossible. I have to create a timer and check the contents of NSPasteboard myself.

Is this a way to do it? Or are there any notifications?

+6
objective-c cocoa
source share
2 answers

Yes, you, in fact, should poll the file cabinet to see if its contents have changed. This is not ideal, but it is possible. Basically, you have a timer that fires once or twice per second and checks -[NSPasteboard changeCount] . If changeCount changes, it means that the contents of the cardboard have also changed (or at least there is a new owner).

+11
source share

Based on the answer provided by Dave DeLong, I came up with a similar implementation, but in quick, here is a link to its essence: PasteboardWatcher.swift

Excerpt from this code:

 class PasteboardWatcher : NSObject { // assigning a pasteboard object private let pasteboard = NSPasteboard.generalPasteboard() // to keep track of count of objects currently copied // also helps in determining if a new object is copied private var changeCount : Int // used to perform polling to identify if url with desired kind is copied private var timer: NSTimer? // the delegate which will be notified when desired link is copied var delegate: PasteboardWatcherDelegate? // the kinds of files for which if url is copied the delegate is notified private let fileKinds : [String] /// initializer which should be used to initialize object of this class /// - Parameter fileKinds: an array containing the desired file kinds init(fileKinds: [String]) { // assigning current pasteboard changeCount so that it can be compared later to identify changes changeCount = pasteboard.changeCount // assigning passed desired file kinds to respective instance variable self.fileKinds = fileKinds super.init() } /// starts polling to identify if url with desired kind is copied /// - Note: uses an NSTimer for polling func startPolling () { // setup and start of timer timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: Selector("checkForChangesInPasteboard"), userInfo: nil, repeats: true) } /// method invoked continuously by timer /// - Note: To keep this method as private I referred this answer at stackoverflow - [Swift - NSTimer does not invoke a private func as selector](http://stackoverflow.com/a/30947182/217586) @objc private func checkForChangesInPasteboard() { // check if there is any new item copied // also check if kind of copied item is string if let copiedString = pasteboard.stringForType(NSPasteboardTypeString) where pasteboard.changeCount != changeCount { // obtain url from copied link if its path extension is one of the desired extensions if let fileUrl = NSURL(string: copiedString) where self.fileKinds.contains(fileUrl.pathExtension!){ // invoke appropriate method on delegate self.delegate?.newlyCopiedUrlObtained(copiedUrl: fileUrl) } // assign new change count to instance variable for later comparison changeCount = pasteboard.changeCount } } } 

Note: in the general code. I am trying to determine if the user has copied the url file or not, the provided code can be easily modified for other general purposes.

+3
source share

All Articles