-1

我的应用程序允许将图像保存到本机文件应用程序。我这样做:

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

4

1 回答 1

1

在做了一些研究之后,我认为这不是不需要的行为,而更像是Snapseed已经订阅的行为,因为这种行为不会自动发生。

但是,有一些错误(我认为)不会让您轻松取消订阅此行为。

我们需要查看的地方是使用LSSupportsOpeningDocumentsInPlaceand CFBundleDocumentTypes,更多关于这里这里的内容:

在这里,我创建了一个小示例,当用户使用您的代码点击按钮时,将图像从应用程序主包保存到文档目录:

与您的代码完全没有区别

@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/>

这支持在文件应用程序中公开您的文档目录,之后一切正常:

将 UIImage 保存到文件应用程序 iOS Swift 中显示的文档目录

但是,如果您希望您的应用程序成为打开某些文件格式的组的一部分,您可以修改您的 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 中显示的行为,它会打开应用程序而不是文件应用程序中的预览

从文件应用程序 iOS Swift 在我的应用程序中打开图像

不幸的是,似乎一旦将此行为分配给您的应用程序,即使您从 info.plist 中删除上述键,此行为仍然存在。

我可以恢复原始行为的唯一方法是使用一个新的包标识符,并且只使用这两个键,info.plist以便将您的文档目录公开给 Files 应用程序

<key>UIFileSharingEnabled</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>

我相信这是某种错误,因为应该有一种简单的方法来取消订阅这种行为。

希望这会有所帮助,即使它不能完全解决您的问题

于 2022-03-02T12:09:44.830 回答