我的沙盒装 macOS应用程序按照惯例通过NSOpenPanel
模态窗口导入用户选择的图像文件。
首先,我将面板配置为canChooseDirectories = false
,并将allowedFileTypes
属性设置为NSImage.imageTypes
。到目前为止一切顺利。
使用该应用程序,我意识到,要导入的图像更多时候不是全部分组在一个文件夹中,而没有更多内容。如果我可以让用户仅选择包含的文件夹并在“批发”中导入图像,那就太好了,所以我采用了以下代码:
let panel = NSOpenPanel()
panel.allowsMultipleSelection = true
panel.canChooseDirectories = true
panel.canCreateDirectories = false
panel.canChooseFiles = true
panel.allowedFileTypes = NSImage.imageTypes
panel.begin { [unowned self] (result) in
guard result == .OK else {
return // User cancelled
}
// Read all selected images:
let urls: [URL] = {
if let directory = panel.directoryURL {
// .........................................
// [A] One directory selected:
do {
let urls = try FileManager.default.contentsOfDirectory(at: directory, includingPropertiesForKeys: nil, options: [])
return urls
} catch {
// (I ALWAYS END UP HERE)
print(error.localizedDescription)
return []
}
} else {
// .........................................
// [B] One or more files selected:
return panel.urls
}
}()
// (next: read individual urls...)
...但是try
语句总是失败,执行catch
块并且抛出的错误是:
“由于您无权查看文件“ MyImageFolder”,因此无法打开它。”
是否有解决沙盒应用程序的方法?我忘记了什么,可以让我读取用户选择的文件夹的内容吗?
附录: Apple's documentation指出:
应用程序的用户指定他们要使用文件或文件夹时,系统会将关联的路径添加到应用程序的沙箱中。举例来说,用户将〜/ Documents文件夹拖到应用程序的Dock磁贴上(或拖到应用程序的Finder图标上,或拖到应用程序的打开窗口中),从而表明他们要使用该文件夹。作为响应,系统会将〜/ Documents文件夹,其内容及其子文件夹提供给您的应用。
(重点是我的)
答案 0 :(得分:0)
我过早接受了@vadian's quick answer,但似乎我可以从NSOpenPanel
访问用户选择的文件夹中的各个文件。
在阅读this answer(我一开始在某种程度上错过了我的搜索)后,我发现下面的代码有效:
// Warning! This code does not deal with the user selecting
// multiple folders!
let urls: [URL] = {
if inputURLs.count == 1, inputURLs[0].hasDirectoryPath {
// Folder; Read its contents:
do {
let urls = try FileManager.default.contentsOfDirectory(at: inputURLs[0], includingPropertiesForKeys: nil, options: [])
return urls
} catch {
// (todo: Handle Errors)
return []
}
} else {
// One or more images; Read them directly:
return inputURLs
}
}()
我似乎犯的另一个错误是使用NSURL
的{{1}}属性来区分所选文件夹和单个文件:它为文件夹返回isFileURL
也是!
因此,当我从使用true
切换为使用panel.directoryURL
(当panel.urls[0]
为isFileURL
时)后,我的应用尝试从目录URL读取单个图像。没有违反沙箱的行为,但也没有读取图像。
根据文档,该属性返回true
“如果接收者使用文件方案”(无论如何)。我猜文件夹也“使用文件方案”。
按照this other answer的建议,我改用true
。