iOS:在本机文件应用程序中打开保存的图像
iOS: Open saved image inside the native Files app
我的应用程序允许将图像保存到本机文件应用程序。我这样做:
func save(imageData: Data,
toFolder folderName: String,
withFileName fileName: String) {
DispatchQueue.global().async {
let manager = FileManager.default
let documentFolder = manager.urls(for: .documentDirectory, in: .userDomainMask).last
let folder = documentFolder?.appendingPathComponent(folderName)
let file = folder?.appendingPathComponent(fileName)
do {
try manager.createDirectory(at: folder!, withIntermediateDirectories: true, attributes: [:])
if let file = file {
try imageData.write(to: file)
}
} catch {
print(error.localizedDescription)
}
}
}
但是,当我在“文件”应用程序中点击图片时,系统会导航到我的应用程序,而不是在“文件”应用程序中打开图片。
如何更改?
发生在 Snapseed 应用程序(Google 的应用程序)上的相同不良行为示例
https://media.giphy.com/media/Odnyy9J52HJjhmr0Fl/giphy.gif
经过一些研究,我认为这不是不需要的行为,而是 Snapseed
订阅的行为,因为这种行为不会自动发生。
但是,有一些错误(我认为)不会让您轻松取消订阅此行为。
我们需要注意的地方是使用 LSSupportsOpeningDocumentsInPlace
和 CFBundleDocumentTypes
,更多关于 here and here:
我在这里创建了一个小示例,当用户使用您的代码点击按钮时,将图像从应用程序主包保存到文档目录:
与您的代码完全没有区别
@objc
private func saveImage()
{
if let imageData
= UIImage(named: "dog")?.jpegData(compressionQuality: 1.0)
{
save(imageData: imageData,
toFolder: "image",
withFileName: "dog.jpeg")
}
}
func save(imageData: Data,
toFolder folderName: String,
withFileName fileName: String)
{
DispatchQueue.global().async
{
let manager = FileManager.default
let documentFolder = manager.urls(for: .documentDirectory,
in: .userDomainMask).last
let folder = documentFolder?.appendingPathComponent(folderName)
let file = folder?.appendingPathComponent(fileName)
do {
try manager.createDirectory(at: folder!,
withIntermediateDirectories: true,
attributes: [:])
if let file = file
{
try imageData.write(to: file)
print("file \(fileName) saved")
}
}
catch
{
print(error.localizedDescription)
}
}
}
如果您将以下内容添加到 info.plist
<key>UIFileSharingEnabled</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
这支持在文件应用程序中公开您的文档目录,此后一切正常:
但是,如果您希望您的应用属于打开特定文件格式的组,您可以修改您的 info.plist 以添加 CFBundleDocumentTypes
以建议您的应用能够打开特定文件格式文件,例如我们案例中的图像。
为此,我们将以下内容添加到 info.plist
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>public.image</string>
</array>
<key>CFBundleTypeName</key>
<string>image</string>
<key>LSHandlerRank</key>
<string>Default</string>
</dict>
</array>
这将允许您的应用程序在有人想要共享或打开图像时列出,通过添加它,然后我们得到您的 gif 中显示的行为,即打开应用程序而不是在文件应用程序中预览
不幸的是,似乎一旦将此行为分配给您的应用程序,即使您从 info.plist 中删除上述键,此行为仍然存在。
我可以恢复原始行为的唯一方法是使用新的包标识符,并且只在 info.plist
中使用这两个键,以便将您的文档目录公开给文件应用程序
<key>UIFileSharingEnabled</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
我认为这是某种错误,因为应该有一种简单的方法可以取消订阅此行为。
希望这对您有所帮助,尽管它不能完全解决您的问题
我的应用程序允许将图像保存到本机文件应用程序。我这样做:
func save(imageData: Data,
toFolder folderName: String,
withFileName fileName: String) {
DispatchQueue.global().async {
let manager = FileManager.default
let documentFolder = manager.urls(for: .documentDirectory, in: .userDomainMask).last
let folder = documentFolder?.appendingPathComponent(folderName)
let file = folder?.appendingPathComponent(fileName)
do {
try manager.createDirectory(at: folder!, withIntermediateDirectories: true, attributes: [:])
if let file = file {
try imageData.write(to: file)
}
} catch {
print(error.localizedDescription)
}
}
}
但是,当我在“文件”应用程序中点击图片时,系统会导航到我的应用程序,而不是在“文件”应用程序中打开图片。
如何更改?
发生在 Snapseed 应用程序(Google 的应用程序)上的相同不良行为示例 https://media.giphy.com/media/Odnyy9J52HJjhmr0Fl/giphy.gif
经过一些研究,我认为这不是不需要的行为,而是 Snapseed
订阅的行为,因为这种行为不会自动发生。
但是,有一些错误(我认为)不会让您轻松取消订阅此行为。
我们需要注意的地方是使用 LSSupportsOpeningDocumentsInPlace
和 CFBundleDocumentTypes
,更多关于 here and here:
我在这里创建了一个小示例,当用户使用您的代码点击按钮时,将图像从应用程序主包保存到文档目录:
与您的代码完全没有区别
@objc
private func saveImage()
{
if let imageData
= UIImage(named: "dog")?.jpegData(compressionQuality: 1.0)
{
save(imageData: imageData,
toFolder: "image",
withFileName: "dog.jpeg")
}
}
func save(imageData: Data,
toFolder folderName: String,
withFileName fileName: String)
{
DispatchQueue.global().async
{
let manager = FileManager.default
let documentFolder = manager.urls(for: .documentDirectory,
in: .userDomainMask).last
let folder = documentFolder?.appendingPathComponent(folderName)
let file = folder?.appendingPathComponent(fileName)
do {
try manager.createDirectory(at: folder!,
withIntermediateDirectories: true,
attributes: [:])
if let file = file
{
try imageData.write(to: file)
print("file \(fileName) saved")
}
}
catch
{
print(error.localizedDescription)
}
}
}
如果您将以下内容添加到 info.plist
<key>UIFileSharingEnabled</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
这支持在文件应用程序中公开您的文档目录,此后一切正常:
但是,如果您希望您的应用属于打开特定文件格式的组,您可以修改您的 info.plist 以添加 CFBundleDocumentTypes
以建议您的应用能够打开特定文件格式文件,例如我们案例中的图像。
为此,我们将以下内容添加到 info.plist
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>public.image</string>
</array>
<key>CFBundleTypeName</key>
<string>image</string>
<key>LSHandlerRank</key>
<string>Default</string>
</dict>
</array>
这将允许您的应用程序在有人想要共享或打开图像时列出,通过添加它,然后我们得到您的 gif 中显示的行为,即打开应用程序而不是在文件应用程序中预览
不幸的是,似乎一旦将此行为分配给您的应用程序,即使您从 info.plist 中删除上述键,此行为仍然存在。
我可以恢复原始行为的唯一方法是使用新的包标识符,并且只在 info.plist
中使用这两个键,以便将您的文档目录公开给文件应用程序
<key>UIFileSharingEnabled</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
我认为这是某种错误,因为应该有一种简单的方法可以取消订阅此行为。
希望这对您有所帮助,尽管它不能完全解决您的问题