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.
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. :
override func makeWindowControllers() {
// Returns the Storyboard that contains your Document window.
let storyboard = NSStoryboard(name: "Main", bundle: nil)
if let windowController = storyboard.instantiateController(withIdentifier: "Document Window Controller") as? NSWindowController {
addWindowController(windowController)
if let contentVC = windowController.contentViewController as? MyViewManager {
// NSPersistentdocument creates the managedObjectComtext itself:
contentVC.representedObject = self.managedObjectContext
contentViewController = contentVC
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.