macOS sandbox 文件夹授权
macOS如果想上苹果市场发布的话,那么必须要遵守苹果的沙盒协议,这样应用的存储默认都是沙盒路径,隔离了用户的文件系统,那么这个时候我需要访问 /User/xxx/Library/Developer/ 这种文件夹的时候,直接访问是会被拒绝的,那既然这样就肯定要授权了,等同意了在访问就名正言顺了。
那么要如何进行这种操作呢,首先想到的肯定是先把这个文件夹打开再说,然后当次的权限就有了,然后就是解决后续依然有权限访问的问题,这个时候就用到了 bookmark,这个东东就是转门干这个用的,下面一步一步的来实现这个功能。
本例子以授权 /user/xxx/Library/Developer/ 路径为例。
首先获取到文件绝对路径。
func getAbsolutePath(path: String) -> String? {
let pw = getpwuid(getuid())
guard let home = pw?.pointee.pw_dir else {
return nil
}
let homePath = FileManager.default.string(withFileSystemRepresentation: home, length: Int(strlen(home)))
return "(homePath)/(path)"
}
let path = getAbsolutePath("/Library/Developer")
// /User/xxx/Library/Developer/
打开文件夹获取权限
func openFinder() {
let fm = FileManager.default
let filepath = getAbsolutePath(path: "Library/Developer/")!
print("filepath is (filepath)")
let url = URL(filePath: filepath)
let dialog = NSOpenPanel()
dialog.message = "文件夹授权以提供服务"
dialog.prompt = "选择"
dialog.allowsOtherFileTypes = false
dialog.canChooseFiles = false
dialog.canChooseDirectories = true
dialog.directoryURL = url
dialog.begin { response in
if response == .OK, let folderPath = dialog.url {
// 可以判断一下是不是想要的文件夹,这个时候已经有权限了。
// 保存书签权限
}
}
}
保存书签权限
把书签数据保存在bookmark中,以后用的时候再取出来用。
private func saveBookmarkData(for workDir: URL) {
do {
let bookmarkData = try workDir.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
print("save book mark data")
// save in UserDefaults
UserDefaults.standard.setValue(bookmarkData, forKey: "bookmark")
} catch {
print("Failed to save bookmark data for (workDir)", error)
}
}
判断路径是否授权过
private func restoreFileAccess() -> Bool {
do {
if let bookmark = UserDefaults.standard.object(forKey: "bookmark") as? Data {
var isStale = false
let url = try URL(resolvingBookmarkData: bookmark, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale)
guard url.startAccessingSecurityScopedResource() else {
return false
}
return true
}
return false
} catch {
print("Error resolving bookmark:", error)
return false
}
}
完整代码
import SwiftUI
struct ContentView: View {
@State var fileSize: Int = 0
@State var canAccess: Bool = false
func getAbsolutePath(path: String) -> String? {
let pw = getpwuid(getuid())
guard let home = pw?.pointee.pw_dir else {
return nil
}
let homePath = FileManager.default.string(withFileSystemRepresentation: home, length: Int(strlen(home)))
return "(homePath)/(path)"
}
private func saveBookmarkData(for workDir: URL) {
do {
let bookmarkData = try workDir.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
print("save book mark data")
// save in UserDefaults
UserDefaults.standard.setValue(bookmarkData, forKey: "bookmark")
} catch {
print("Failed to save bookmark data for (workDir)", error)
}
}
private func restoreFileAccess() -> Bool {
do {
if let bookmark = UserDefaults.standard.object(forKey: "bookmark") as? Data {
var isStale = false
let url = try URL(resolvingBookmarkData: bookmark, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale)
guard url.startAccessingSecurityScopedResource() else {
return false
}
return true
}
return false
} catch {
print("Error resolving bookmark:", error)
return false
}
}
func openFinder() {
let fm = FileManager.default
let filepath = getAbsolutePath(path: "Library/Developer/")!
print("filepath is (filepath)")
let url = URL(filePath: filepath)
let dialog = NSOpenPanel()
dialog.message = "Choose your directory"
dialog.prompt = "Choose"
dialog.allowsOtherFileTypes = false
dialog.canChooseFiles = false
dialog.canChooseDirectories = true
dialog.directoryURL = url
dialog.begin { response in
if response == .OK, let folderPath = dialog.url {
saveBookmarkData(for: folderPath)
}
}
}
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("占用容量: (fileSize)")
Button {
if !canAccess {
openFinder()
}
} label: {
if canAccess {
Text("已授权")
} else {
Text("授权")
}
}
}
.padding()
.onAppear {
if restoreFileAccess() {
canAccess = true
} else {
canAccess = false
}
print("access is (canAccess)")
}
}
}
#Preview {
ContentView()
}
原文地址:https://blog.csdn.net/xo19882011/article/details/134787254
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_42548.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。