Kenny Wyland
Kenny Wyland

Reputation: 21870

No events received when using DispatchSource.makeFileSystemObjectSource() to monitor changes to file

I found this article about watching for changes and I've tried to follow along properly. My dispatch source gets created, but I never receive any events.

To make sure I was getting anything and everything, I made sure to set the eventMask = .all.

override func viewDidAppear() {
    super.viewDidAppear()

    Task {
        self.configurl = await self.openfile(forkey: self.keybookmarkconfig)
                    
        if let url = self.configurl {
    
            print("creating filehandle for \(url.absoluteString)")
            self.configfilehandle = try FileHandle(forReadingFrom: url)
    
            print("creating dispatch source to watch \(url.absoluteString)")
            self.source = DispatchSource.makeFileSystemObjectSource(
                fileDescriptor: self.configfilehandle.fileDescriptor,
                eventMask: .all,
                queue: DispatchQueue.main
            )
    
            print("setting event handler for dispatch source")
            self.source.setEventHandler {
                print("config file changed")
            }
    
            print("done with watcher setup")
    
        }

        
    }
    
}

I tried updating the file in numerous ways. I edited/saved it in BBEdit and TextEdit, but because of the warning about how those types of editors might delete/recreate the file, also I tried editing it from the command line with vim. I even did echo "test" >> myfile.txt. But I never received any events in my event handler. I restarted my app in between each of these tests, so I had a fresh file handle.

Any idea why I'm not receiving any event callbacks?

Upvotes: 1

Views: 651

Answers (1)

siegel
siegel

Reputation: 970

After the dispatch source has been created, you have to call self.source.activate() so that the source gets scheduled and started. Otherwise it's just sitting there.

From the documentation:

After creating the dispatch source, use the methods of the DispatchSourceProtocol protocol to install the event handlers you need. The returned dispatch source is in the inactive state initially. When you are ready to begin processing events, call its activate() method.

Upvotes: 3

Related Questions