计算机重新启动后,Swift Url书签权限丢失
我正在开发一个macOS音乐应用程序,提示用户选择一个库目录。选择后,将扫描目录,并在核心数据中创建音乐对象。为了保留对目录及其内容的url的权限,我将目录url存储为书签。简化代码:计算机重新启动后,Swift Url书签权限丢失,swift,macos,Swift,Macos,我正在开发一个macOS音乐应用程序,提示用户选择一个库目录。选择后,将扫描目录,并在核心数据中创建音乐对象。为了保留对目录及其内容的url的权限,我将目录url存储为书签。简化代码: let directoryAndPermissionsKey: String = "" // Key for storing url to UserDefaults /// Saves directory and permissions func storeDirectoryAndPermissions(fo
let directoryAndPermissionsKey: String = "" // Key for storing url to UserDefaults
/// Saves directory and permissions
func storeDirectoryAndPermissions(for directory: URL) throws -> Void {
// Saves directory and permissions
do {
// Creates bookmark
let bookmark: Data = try directory.bookmarkData(options: .securityScopeAllowOnlyReadAccess, includingResourceValuesForKeys: nil, relativeTo: nil)
// Stores directory and permissions
UserDefaults.standard.removeObject(forKey: directoryAndPermissionsKey)
UserDefaults.standard.set(bookmark, forKey: directoryAndPermissionsKey)
// Throws error
} catch {
throw PersistentLibraryError.cannotSaveDirectory
}
}
/// Retrieves directory
func retrieveDirectoryUrl() -> URL? {
// Indicates if data is stale
var isStale: Bool = false
// Makes sure that directory and permissions are stored
guard
UserDefaults.standard.object(forKey: directoryAndPermissionsKey) != nil,
let bookmarkData = UserDefaults.standard.object(forKey: directoryAndPermissionsKey) as? Data,
let directory = try? URL(resolvingBookmarkData: bookmarkData, bookmarkDataIsStale: &isStale)
else {
return nil
}
// Starts accessing directory
_ = directory.startAccessingSecurityScopedResource()
// Returns directory
return directory
}
另外,在plist文件中,我包含以下行:
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>
任何帮助都将不胜感激。创建书签
文件:
当与带有Security Scope的选项组合时
它应该与和securityscope
相结合,这就是您所缺少的
let bookmark:Data=try directory.bookmarkData(选项:[.with securityscope、.securityScopeAllowOnlyReadAccess],包括资源值rkeys:nil,relativeTo:nil)
解析书签
文件:
要解析安全范围的书签以支持应用程序沙盒,请包括with securityscope
选项
这是解析书签时缺少的第二件事
let directory=try?URL(解析bookmarkData:bookmarkData,选项:[.with securityscope],relativeTo:nil,bookmarkDataIsStale:&isStale)
虽然这可以解决您的问题,但请注意您没有处理isStale
。如果书签数据为true
,则必须更新它。您似乎没有处理isStale==true
。当它失败时,isStale
是否为true
?我还认为您必须将.securityScopeAllowonReadAccess
与相结合。与securityScope
相结合。不,我刚刚检查过。当我添加新目录并授予权限时,将返回false
。我重新启动了计算机,但仍然返回了false
,但现在,无法初始化AV音频播放器。。在重新启动应用程序后,使用Security Scope
实际上破坏了权限,更不用说重新启动计算机了我刚刚注意到的另一件事是,在解析书签(URL(resolvingBookmarkData:bookmarkData,options:[.withSecurityScope],…)
)时,您没有传递。
Error Domain=NSOSStatusErrorDomain Code=-54 "permErr: permissions error (on file open)"