У меня проблемы (в Мохаве и Каталине) с «повторным использованием» закладки URL-адреса области безопасности для папки между запусками приложения в моем приложении.
Это простое приложение для распаковки, использующее libarchive
framework. Пользователь выбирает файл для распаковки, я хочу сохранить закладку URL для его родительской папки (например, ~ / Desktop) и использовать его повторно, когда пользователь в следующий раз попытается распаковать файл в той же папке.
Сначала я добавил следующее вФайл разрешений моего приложения:
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
При первом обращении к файлу (соответственно к родительской папке):
- Пользователь выбирает файл для распаковки
- Я представляю
NSOpenPanel
для получения доступа к папке с файлами:
let directoryURL = fileURL.deletingLastPathComponent()
let openPanel = NSOpenPanel()
openPanel.allowsMultipleSelection = false
openPanel.canChooseDirectories = true
openPanel.canCreateDirectories = false
openPanel.canChooseFiles = false
openPanel.prompt = "Grant Access"
openPanel.directoryURL = directoryURL
openPanel.begin { [weak self] result in
guard let self = self else { return }
// WARNING: It's absolutely necessary to access NSOpenPanel.url property to get access
guard result == .OK, let url = openPanel.url else {
// HANDLE ERROR HERE ...
return
}
// We got URL and need to store bookmark's data
// ...
}
Я получаю данные закладки из
папки URL и сохраняю их в архиве с ключами:
let data = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
bookmarks[url] = data
NSKeyedArchiver.archiveRootObject(bookmarks, toFile: bookmarksPath)
Теперь я начинаю использовать
file URL и использую
libarchive
для распаковки .zip файла в его родительскую папку:
fileURL.startAccessingSecurityScopedResource()
// Decompressing file with libarchive...
fileURL.stopAccessingSecurityScopedResource()
Все работает как положено, ZIP-файл распаковывается
При перезапуске приложения распаковываете файл в той же папке, повторно используя сохраненные данные закладок:
- Я получаю закладки из архива ключей:
let bookmarks = NSKeyedUnarchiver.unarchiveObject(withFile: bookmarksPath) as? [URL: Data]
Я получаю данные закладок из закладок для родительской папки файла и разрешаю их:
let directoryURL = fileURL.deletingLastPathComponent()
let data = bookmarks[directoryURL]!
var isStale = false
let newURL = try URL(resolvingBookmarkData: data, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale)
Теперь я снова начинаю использовать
file URL и использую
libarchive
для распаковки .zip файла в его родительскую папку:
fileURL.startAccessingSecurityScopedResource()
// Decompressing file with libarchive...
fileURL.stopAccessingSecurityScopedResource()
Но на этот раз libarchive
возвращаетсяошибка: Failed to open \'/Users/martin/Desktop/Archive.zip\'
Я знаю, что могу делать что-то ужасно неправильное или не понимать концепцию URL-адресов закладок в области безопасности, но не могу найти, в чем проблема. Есть подсказки?
ЗАКЛЮЧИТЕЛЬНОЕ РЕШЕНИЕ Ответ Rckstr и ответ в этой ветке форума разработчиков Apple указали мне правильное направление. Абсолютно необходимо позвонить startAccessingSecurityScopedResource()
в тот же момент, когда URL-адрес, возвращенный try URL(resolvingBookmarkData: data, options: .withSecurityScope ...