Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 533
eivindml Avatar asked May 20 '18 21:05

eivindml


2 Answers

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.

like image 69
Marc T. Avatar answered Oct 31 '22 06:10

Marc T.


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)
like image 38
Paul Avatar answered Oct 31 '22 07:10

Paul