eivindml
eivindml

Reputation: 2539

Swift / Cocoa: How to watch folder for changes?

I'm writing a small macOS app, where I want to be able to watch a folder for changes. It doesn't need to watch subfolder, I only want to receive a notification if a file is added to the folder or removed.

It looks like NSFileCoordinator and/or NSFilePresenter could be used to achieve this, but I was not able to understand how to use them to achieve this.

Ideally this can be solved without having to include a third party framework.

Upvotes: 20

Views: 4817

Answers (2)

Marc T.
Marc T.

Reputation: 5340

You can do this using NSFilePresenter. The observing class must conform to NSFilePresenter as shown below.

The presentedItemURL would point to the folder you want to observe. If there is a change in the folder presentedSubitemDidChangeAtURL get called. The code snipped below could give you an idea how it can work.

class ObservingClass: NSObject, NSFilePresenter {

    lazy var presentedItemOperationQueue = NSOperationQueue.mainQueue()
    var presentedItemURL:NSURL?
    

    func presentedSubitemDidChangeAtURL(url: NSURL) {
        let pathExtension = url.pathExtension    
        if pathExtension == "png"{
            refreshImages()
        }
    }

   func refreshImages(){
        let path = snapshotPath
        var isDirectory: ObjCBool = ObjCBool(false)
        
        if NSFileManager.defaultManager().fileExistsAtPath(path!, isDirectory: &isDirectory){
            if isDirectory{
                do {
                    let list = try NSFileManager.defaultManager().contentsOfDirectoryAtPath(path!) as Array<String>
                    for filePath in list {
                        if filePath.hasSuffix(".png"){
                            if let snapshot = snapshotAtPath(path! + "/" + filePath){
                                newSnapshotArray += [snapshot]
                            }
                        }
                    }
                } catch {
                    // error handling 
                }
            }
        }
    }
}

Best wishes.

Upvotes: 20

Paul
Paul

Reputation: 91

Marc T's answer still works and seems to be the easiest solution for this.

To make it work I needed to add the following line (could be at the init() of ObservingClass):

NSFileCoordinator.addFilePresenter(self)

Upvotes: 8

Related Questions