swift - 如何从 macOS 应用程序中的文件系统读取图像
问题描述
May 应用程序会打开一个对话框,允许选择图像并将其显示给用户。用户选择图像的代码是:
let myFiledialog = NSOpenPanel()
myFiledialog.prompt = "Upload image"
myFiledialog.canChooseDirectories = false
myFiledialog.canChooseFiles = true
myFiledialog.allowedFileTypes = ["png", "jpg", "jpeg"]
myFiledialog.allowsMultipleSelection = false
myFiledialog.begin { [weak self] result -> Void in
guard
result.rawValue == NSApplication.ModalResponse.OK.rawValue,
let selectedPath = myFiledialog.url?.path
else {
return
}
guard let image = NSImage(contentsOfFile: selectedPath) else {
return
}
someImageView.image = image
UserDefaults.standard.set(selectedPath, forKey: "imagePath")
}
我正确显示图像。这个想法是用户可以关闭应用程序,打开它并查看图像。
我得到图像名称:
let pathName = UserDefaults.standard.string(forKey: "imagePath")
我比较了设置一个断点,pathName == selectedPath
它们是相等的。
然而,做
NSImage(contentsOfFile: pathName!)
是nil
。
这是否与我需要获取读取文件系统中的数据的权限有关?我应该将用户图像保存在可以访问它们的其他地方吗?也许 NSUserDefaults 也是images.data
?
我很感激帮助。
解决方案
感谢@matt 评论中的链接,我实现了答案。把它留在这里以防对任何人有帮助。
- 向应用程序添加权利。点击 App -> Target -> Signin & Capabilities -> App Sandbox 并更改文件访问类型的“权限和访问”。Xcode 会询问您是否要创建授权文件。接受。如果您不需要它,请还原您所做的更改。现在您将拥有该文件
<AppName>/<AppName>Release.entitlements
。添加允许用户使用应用范围内的书签和 URL ( Apple Docs ) 的权利。这是文件的样子:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>
</dict>
</plist>
- 创建一个
Codable
保存书签数据和图像名称(或Codable
您可能拥有并需要保存的任何数据)的结构。
struct CodableImage: Codable {
let bookmarkData: Data
let name: String
}
- 为网址添加书签:
do {
let data = try url.bookmarkData()
let codableImage = CodableImage(bookmarkData: data, name: "Awesome image")
UserDefaults.standard.set(try? JSONEncoder().encode(codableImage), forKey: "kImageKey")
} catch {
print(error)
}
- 检索数据
首先获取CodableImage
来自UserDefaults
:
guard
let encodedImageData = UserDefaults.standard.value(forKey: "kImageKey") as? Data,
let codableImage = try? JSONDecoder().decode(CodableImage.self, from: encodedImageData)
else {
// Data could not be read or decoded or both :(
return
}
解析书签数据并在已解决的书签过时更新书签:
var isBookmarkStale = false
guard let url = try? URL(resolvingBookmarkData: codableImage.bookmarkData, bookmarkDataIsStale: &isBookmarkStale) else {
return nil
}
if isBookmarkStale {
print("Bookmark is stale. renewing.")
// If bookmark data is stale, all occurences have to be updated.
let _ = try? url.bookmarkData()
}
最后,从解析的 url 创建图像:
let image = NSImage(contentsOf: url)
推荐阅读
- c# - aspnetcore web 项目导入另一个项目的控制器
- iis - 在 W3SVC99 之后不再创建 inetpub 日志
- angular - 使用 ngrx 处理复杂模型
- android - xml文件中的livedata观察者和数据绑定监听器是否被并行触发?
- react-native - 在 React-Native 的 Alert 上出现 this.state
- vb.net - 分配到 DataGridView 后如何更改 RichTextBox 的背景颜色
- html - 显示 flex 不允许内联文本对齐和样式
- r - 使用 dplyr 从第二行跨多列更改 R 数据帧
- android - 我的应用程序因 setOnCameraIdleListener 崩溃
- python - 将 OpenCV 与 PyInstaller 一起使用