That may be a very partial answer which I hope will be relevant for your question.
My point was to be able to create a file in a sandboxed environment, XCode 8.3.
I did the following :
- call NSOpenPanel, just for selecting a directory where to authorize writing
- inside the completion handler of NSOpenPanel, call NSSavePanel to proceed with file creation.
And that finally worked.
Here is some code (I edited, so there may be some typos):
@IBAction func newDossier(_ sender: NSMenuItem) { // I answer to a menu selection
let openPanel = NSOpenPanel()
openPanel.message = "Choisir le dossier où enregistrer vos fichiers\n(Necassaire pour la gestion de la sécurité de l'ordinateur)" // let user understand why we ask to select just a directory
openPanel.prompt = "Choisir"
openPanel.canChooseFiles = false
openPanel.canChooseDirectories = true
openPanel.canCreateDirectories = true
openPanel.begin() {
(result2) -> Void in
if (result2 == NSFileHandlingPanelOKButton) {
globalAllowedFolderUrl = openPanel.url! // I save URL for later use
storeBookmark(url: globalAllowedFolderUrl)
Swift.print("allowedFolderUrl ", GlobalData.sharedGlobal.allowedFolderUrl)
let savePanel = NSSavePanel() // Now we proceed with savePanel
savePanel.title = "Fichier de listes"
savePanel.nameFieldStringValue = "default name"
savePanel.prompt = "Créer"
savePanel.allowedFileTypes = ["xxxx"] // your file extension, if needed
let fileManager = FileManager.default
savePanel.begin() { (result) -> Void in
if (result == NSFileHandlingPanelOKButton) {
let fileWithExtensionURL = savePanel.url!
globalDocURL=: fileWithExtensionURL // savePanel.URL! in a global
if fileManager.fileExists(atPath: fileWithExtensionURL.path) { // file exists, warn user
let fileName = fileWithExtensionURL.deletingPathExtension().lastPathComponent
let folderName = fileWithExtensionURL.deletingLastPathComponent().lastPathComponent
self.errorExistingFile(fileName: fileName, folderName: folderName)
} else { // We can create the file
saveIFile() // That's where we write data
saveBookmarks() // save the folder url; you know this func already
}
} // result == NSModalResponseOK
} // beginWithCompletionHandler
}
}
}
func saveFile() {
if globalAllowedFolderUrl == nil {
print("No file, not saved")
} else {
let data = NSMutableData()
let archiver = NSKeyedArchiver(forWritingWith: data)
// encode data
archiver.finishEncoding()
let fileName = globalDocURL.lastPathComponent
let fileUrl = = globalAllowedFolderUrl.appendingPathComponent(fileName)
do {
try data.write(to: fileUrl, options: [.atomic])
} catch {
Swift.print(error)
return
}
}
}