Save/Copy a file from Bundle to Desktop using NSSavePanel

余生长醉 提交于 2019-12-11 03:18:48

问题


I’m creating a macOS app which ships with some .zip files within its Bundle directory.

Users should be able to save these files from my app to a custom directory.

I found NSSavePanel and thought it is the right approach — that’s what I have so far:

@IBAction func buttonSaveFiles(_ sender: Any) {

    let savePanel = NSSavePanel()

    let bundleFile = Bundle.main.resourcePath!.appending("/MyCustom.zip")

    let targetPath = NSHomeDirectory()
    savePanel.directoryURL = URL(fileURLWithPath: targetPath.appending("/Desktop")) 
    // Is appeding 'Desktop' a good solution in terms of localisation?

    savePanel.message = "My custom message."
    savePanel.nameFieldStringValue = "MyFile"
    savePanel.showsHiddenFiles = false
    savePanel.showsTagField = false
    savePanel.canCreateDirectories = true
    savePanel.allowsOtherFileTypes = false
    savePanel.isExtensionHidden = true

    savePanel.beginSheetModal(for: self.view.window!, completionHandler: {_ in })

}

I couldn’t find out how to 'hand over' the bundleFile to the savePanel.

So my main question is: How can I save/copy a file from the app bundle to a custom directory?

Additional questions depending NSSavePanel: 1) It seems that it’s not localized by default (my Xcode scheme is set to German, but the panel appears in English), do I have to customize that by myself? 2) Is there a way to present the panel expanded by default?


回答1:


You should use Bundle.main.url to get your existing file URL, then get the destination URL with the panel, then copy the file. The panel doesn't do anything to files, it just gets their URL.

Example:

// the panel is automatically displayed in the user's language if your project is localized
let savePanel = NSSavePanel()

let bundleFile = Bundle.main.url(forResource: "MyCustom", withExtension: "zip")!

// this is a preferred method to get the desktop URL
savePanel.directoryURL = FileManager.default.urls(for: .desktopDirectory, in: .userDomainMask).first!

savePanel.message = "My custom message."
savePanel.nameFieldStringValue = "MyFile"
savePanel.showsHiddenFiles = false
savePanel.showsTagField = false
savePanel.canCreateDirectories = true
savePanel.allowsOtherFileTypes = false
savePanel.isExtensionHidden = true

if let url = savePanel.url, savePanel.runModal() == NSFileHandlingPanelOKButton {
    print("Now copying", bundleFile.path, "to", url.path)
    // Do the actual copy:
    do {
        try FileManager().copyItem(at: bundleFile, to: url)
    } catch {
        print(error.localizedDescription)
    }
} else {
    print("canceled")
}

Also, note that the panel being expanded or not is a user selection, you can't force it from your app.



来源:https://stackoverflow.com/questions/41197760/save-copy-a-file-from-bundle-to-desktop-using-nssavepanel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!