NSOpenPanel в «Песочнице» - доступ ко всем файлам в папке, выбранной пользователем - PullRequest
2 голосов
/ 18 марта 2019

Моя песочница Приложение 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, ее содержимое и ее подпапки доступными для вашего приложения.

(выделено мной)

1 Ответ

0 голосов
/ 19 марта 2019

Я принял быстрый ответ @ 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
    }
}()

Еще одна ошибка, которую яказалось, что он использует NSURL свойство isFileURL, чтобы различать выбранную папку и один файл: она возвращает true и для папки!

Так что послеЯ переключился с использования panel.directoryURL на использование panel.urls[0] (когда isFileURL равно true), мое приложение пыталось прочитать одно изображение из URL-адреса каталога.Никаких нарушений в песочнице, но также и чтение изображений.

Согласно документам, это свойство возвращает true "если получатель использует файловую схему" (что бы это ни значило).Я думаю, папки тоже "использовать схему файлов".Вместо этого я переключился на hasDirectoryPath, как предложено в этом другом ответе .

...