0

I'm an experienced iOS developer but I'm new to developing for macOS. In this app, the user has chosen a file and I want to monitor that file for any changes so that my app can respond, read the new contents of the file, and act appropriately.

I found this article about watching for changes and have been following along, but I get a strange crash/break when I run the app. The code looks like this:

screenshot of code with crash/break

I don't get any error message in the console. No stack trace. I don't have any breakpoints set. If I comment out the source.setEventHandler lines I still get the same crash/break. If I comment out the let source = DispatchSource.makeFileSystemObjectSource() lines, then the code runs fine.

The url in question is a security-scoped url that was previously chosen with an NSOpenPanel() and then stored as a security-scoped bookmark.

Am I doing something wrong? I'm new to Swift 5.5 concurrency, is that causing the problem?

How can I properly watch a file for changes so that my app can automatically respond?


Text version of code for accessibility:

override func viewDidAppear() {
    super.viewDidAppear()

    Task {
        self.configurl = await self.openfile(forkey: self.keybookmarkconfig)
                    
        if let url = self.configurl {
            
            let configfilehandle = try FileHandle(forReadingFrom: url)
            
            let source = DispatchSource.makeFileSystemObjectSource(
                fileDescriptor: configfilehandle.fileDescriptor,
                eventMask: .extend,
                queue: DispatchQueue.main
            )
            
            source.setEventHandler {
                print("config file changed")
            }
            
        }
        
    }
    
}
Kenny Wyland
  • 20,844
  • 26
  • 117
  • 229
  • What happens if you remove `Task {`? Shouldn't you keep a strong reference to `source`? In the article `source` is a property. – Willeke Nov 21 '22 at 20:44
  • @Willeke Ah, the strong reference was the issue. (At least, the code doesn't crash now. It's not calling back my event handler, but at least it's not crashing). I always write my code with `self.blah` whenever I'm referencing properties (even though its not needed) because when I'm reading it I always want to be reminded that is a property. So when I looked at their code without the `self.` I wrongly assumed it was a local variable. I entirely missed that it didn't have a `let` before the source. Please post this as the solution and I'll accept it! – Kenny Wyland Nov 22 '22 at 01:59
  • I'm just guessing. – Willeke Nov 26 '22 at 09:00

0 Answers0