簡體   English   中英

沙箱下的NSOpenPanel-訪問“用戶選定”文件夾中的所有文件

[英]NSOpenPanel under Sandbox - Access All Files inside User Selected folder

按照慣例,我的沙盒 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的文檔指出:

當應用程序的用戶指定他們要使用文件或文件夾時,系統會將關聯的路徑添加到應用程序的沙箱中。 舉例來說,用戶將〜/ Documents文件夾拖到應用程序的Dock磁貼上(或拖到應用程序的Finder圖標上,或拖到應用程序的打開窗口中),從而表明他們要使用該文件夾。 作為響應,系統使〜/ Documents文件夾, 其內容及其子文件夾可用於您的應用程序。

(強調我的)

我過早接受@vadian的快速解答 ,但看來我可以NSOpenPanel訪問用戶選擇的文件夾內的各個文件。

閱讀了這個答案 (我一開始就以某種方式錯過了這個答案 ),然后發現下面的代碼有效:

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

我似乎isFileURL的另一個錯誤是使用NSURLisFileURL屬性來區分所選文件夾和單個文件: 它也為文件夾返回true

因此,當我從使用panel.directoryURL切換為使用panel.urls[0] (當isFileURLtrue )之后,我的應用嘗試從目錄URL讀取單個圖像。 沒有違反沙箱的行為,但也沒有讀取任何圖像。

根據文檔,“如果接收者使用文件方案”,則該屬性返回true (無論如何)。 我猜文件夾也“使用文件方案”。 我改用hasDirectoryPath ,如其他答案所建議。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM