swiftmacoscocoansfilecoordinatornsfilepresenter

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.


Solution

  • 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.