Get notified when something is added to NSPasteboard

前端 未结 2 1979
野趣味
野趣味 2021-02-06 02:58

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

S

相关标签:
2条回答
  • 2021-02-06 03:16

    Yes, you essentially have to poll the pasteboard to see if its contents have changed. It's not ideal, but it's possible. Basically, you have a timer that fires once or twice a second and checks the -[NSPasteboard changeCount]. If the changeCount changes, that means the contents of the pasteboard have also changed (or there's at least a new owner).

    0 讨论(0)
  • 2021-02-06 03:21

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

    Code snippet from same:

    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 shared code I am trying to identify if user has copied a file url or not, the provided code can easily be modified for other general purposes.

    0 讨论(0)
提交回复
热议问题