My app should import text files. With NSOpenPanel I can select files, and after closing the panel, it should import files one by one. This is done by sending a notification self.nextFile() for each file to an observer who manages the import.
Here is my code nippest:
func selectFiles() {
fileIndex = 0
fileList = [URL]()
recordsImported = 0
numberOfLines = 0
let openPanel = NSOpenPanel()
openPanel.allowsMultipleSelection = true
openPanel.canChooseDirectories = false
openPanel.canCreateDirectories = false
openPanel.canChooseFiles = true
//openPanel.allowedFileTypes = ["csv"] // deprecated !
openPanel.delegate = self
openPanel.accessoryView = loadAccessoryVC!.view as NSView
openPanel.beginSheetModal(for:(NSApplication.shared.mainWindow)!) { (response) in
if response == .OK {
self.fileList = openPanel.urls
self.nextFile(notification: Notification(name:Notification.Name("next file")))
}
openPanel.close()
}
Most of the time it works fine, but sometimes the openPanel.urls is empty - especially if my list is more than 20 files. It looks like the open panel is not yet finished before self.nextFile() is called.
- Xcode version: 14.01
- deployment target : MAC OS 10.15
Any idea how to sync it ? Could @escaping statement in the closure help?
I found the root cause: It is not very easy to describe.
It was a side effect of initialising objects at the wrong place in my code.
The app is a Core Data app, and when I open more than one document, I did not take care to give each document its own importing object and NSManagedObjectContext. When it comes to the notification to import a (next) file, it was calling for both documents. But only one had a list of files; the second was empty
Lesson learned: Initiate objects that belong to a document in NSDocument and not globally ( as in Appdelegate or NSApp..) Use make WindowController as described in Apple´s documentation. :