使用NSSavePanel将文件从Bundle保存到桌面

使用NSSavePanel将文件从Bundle保存到桌面

问题描述:

我正在创建一个macOS应用程序,该应用程序在其Bundle目录中附带一些.zip文件。使用NSSavePanel将文件从Bundle保存到桌面

用户应该能够将这些文件从我的应用程序保存到自定义目录。

我发现NSSavePanel,认为这是正确的做法 - 这是我到目前为止有:

@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 }) 

} 

我无法找出如何“交出”的bundleFilesavePanel

所以我的主要问题是:如何将应用程序包中的文件保存/复制到自定义目录?

其他问题取决于NSSavePanel:1)它似乎没有默认本地化(我的Xcode方案设置为德语,但面板以英文显示),我必须自己定制吗? 2)有没有方法可以展示默认扩展的面板?

+0

运行搜索包或NSBundle将有所帮助。 –

+0

@ElTomato我已经使用'Bundle'来查找bundleFile的路径(参见上面的代码)。这对我描述的问题没有帮助。 – ixany

+0

哦,对不起...让我想想,我会回来的。 –

您应该使用Bundle.main.url来获取您现有的文件URL,然后使用面板获取目标URL,然后复制该文件。该面板对文件不做任何处理,只是获取他们的URL。

例子:

// 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") 
} 

而且,请注意,面板正在扩大与否是用户的选择,你不能从你的应用程序迫使它。

+0

非常感谢!很好的解决方案,工作正常你也不知道为什么'NSSavePanel'没有被翻译/本地化吗?我认为所有系统提供的UI元素都应该自动以相关语言显示。 – ixany

+1

不客气。如果* [您的项目已经本地化],该面板将自动以用户的语言显示*(http://take.ms/x5P8a)。从列表中添加新语言已足够,如果不想实际实现本地化,则不必实现本地化 - 但您必须至少在此列表中添加语言,因为该面板将需要它们。 – Moritz

+1

[适用于Xcode截图的正确链接](https://monosnap.com/file/P6rGrVhQsGaquhVdlzMNDK0FUVXFq6.png)用于添加本地化。 – Moritz