自定义扩展文件在iMessage中无法打开

21

在我的应用程序中,我需要从一个设备发送一些自定义数据文件到另一个设备,并且我正在尝试使用Mail、iMessage/Message和Airdrop实现这一点。

这在Mail和Airdrop中运行良好,但是在iMessage中出现问题,而在接收端,我无法打开这些文件。它根本不允许我对其进行任何操作。

有什么想法吗?

这是我的文档类型:

<key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeIconFile</key>
            <string>abc.png</string>
            <key>CFBundleTypeName</key>
            <string>ABC Custom Data type</string>
            <key>CFBundleTypeRole</key>
            <string>Viewer</string>
            <key>Handler Rank</key>
            <string>Owner</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.company.abc.wd</string>
            </array>
        </dict>
    </array>

这是我发送数据的方式:

NSMutableDictionary * dict = [NSMutableDictionary dictionary];
[dict setObject:currentDataSet forKey:@"actualData"];
NSData * meetingData = [NSKeyedArchiver archivedDataWithRootObject:dict];

Meeting * dataItem = [[Meeting alloc]initWithData:meetingData
               type:@"com.abc.xyz.wd" subject:@"Meeting"
          previewImage:[UIImage imageNamed:@"appIcon.png"]];

UIActivityViewController * activityController =
  [[UIActivityViewController alloc]initWithActivityItems:@[dataItem]
                                   applicationActivities:nil];

activityController.excludedActivityTypes =
       @[UIActivityTypePostToTwitter, UIActivityTypePostToWeibo];

[self presentViewController:activityController animated:YES completion:nil];

不确定是否必须遵循标准的UTIs - https://developer.apple.com/library/ios/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html#//apple_ref/doc/uid/TP40009259-SW1 - 当您将文件附加到消息时,您是否有要尝试的代码示例,是否使用了 addAttachmentData:typeIdentifier:filename: - StuartM
你想只发送PNG文件吗?如果不是,你可以使用下面的代码来发送/检测所有类型的格式: CFBundleTypeIconFiles CFBundleTypeName com.jungleDisk.file LSHandlerRank Owner LSItemContentTypes public.data ``` - MohanVydehi
@Ashutosh,你解决了这个问题吗?我遇到了同样的问题,并找到了这个帖子。 - rjkaplan
3个回答

8

这个答案是正确的,只要符合public.text,自定义文档就可以从信息中打开。但这种解决方案的缺点在于文档以原始文本形式预览,可能不是预期的结果。

符合public.data的文档可以通过创建一个快速查看预览扩展程序而被从信息应用中打开,而无需以原始文本形式预览。虽然没有关于如何构建快速查看预览扩展程序的详细文档,但它相当简单明了:

  1. In Xcode, choose, File > New > Target.

  2. Choose Quick Look Preview Extension, give your extension a name, and click Finish.

  3. In the info.plist for the newly created extension, add a new item under NSExtension > NSExtensionAttributes > QLSupportedContentTypes, and set the value for this item to your app's custom document type. For example:

    ...
    <key>NSExtension</key>
    <dict>
        <key>NSExtensionAttributes</key>
        <dict>
            <key>QLSupportedContentTypes</key>
            <array>
                <string>com.company.abc.wd</string>
            </array>
            <key>QLSupportsSearchableItems</key>
            <true/>
        </dict>
        <key>NSExtensionMainStoryboard</key>
        <string>MainInterface</string>
        <key>NSExtensionPointIdentifier</key>
        <string>com.apple.quicklook.preview</string>
    </dict>
    ...
    
  4. Use MainInterface.storyboard and PreviewViewController to define the layout of your custom Quick Look preview. More specifically, read data from the URL provided in the preparePreviewOfFile function and populate the ViewController accordingly. A brief example (in Swift 4):

    func preparePreviewOfFile(at url: URL, completionHandler handler: @escaping (Error?) -> Void) {
        do {
            let documentData = try Data(contentsOf: url)
    
            // Populate the ViewController with a preview of the document.
    
            handler(nil)
        } catch let error {
            handler(error)
        }
    }
    

我在创建扩展时遇到的一些问题:

  • 导出的 UTI 标识符必须全部小写。如果其中一些字符是大写的,则无法显示快速查看预览,即使在我的快速查看预览扩展中使用了相同的大小写。

  • 快速查看预览扩展不允许链接动态库。如果链接了动态库,则快速查看预览将无法加载。

  • 快速查看 ViewController 不允许有任何按钮。如果包含按钮,则快速查看预览将无法加载。

其他资源:


1
在iOS 14.7中,我发现我可以从“文件”应用程序中打开我的自定义文件格式,但在“信息”中点击其中一个文件时没有任何反应。通过为我的文件类型添加一个非常简单的快速查看功能,我能够在“信息”中查看我的文件。从那个预览中,我可以按照需要发送到我的应用程序。在“文件”应用程序中,它似乎有自己的快速查看功能,但在“信息”中无法使用(直到我自己制作了一个)。 - Jason
我竭尽全力也无法让它工作。我按照你的步骤进行,但没有任何反应。我正在创建新的构建目标,但我不明白如何进行构建?目前我只是创建它,编辑它的info.plist文件,然后构建和运行我的普通应用程序目标。不确定这两者应该如何通信?我的文件在邮件/文件/隔空投送中完美运行。 - Hamster

4
我在搜索类似解决方案时发现了这篇文章。我能够从我的应用程序中发送自定义文件,并在电子邮件中打开它或与AirDrop一起使用。如果我通过iMessage发送它,甚至会显示我的自定义图标,但是当我在iMessage中点击它时,什么也没有发生。
请注意,您需要在plist文件中添加以下内容(来自如何将文件类型与iPhone应用程序关联?)。
<key>UTExportedTypeDeclarations</key>
<array>
    <dict>
        <key>UTTypeConformsTo</key>
    <array>
        <string>public.plain-text</string>
        <string>public.text</string>
    </array>
    <key>UTTypeDescription</key>
    <string>Molecules Structure File</string>
    <key>UTTypeIdentifier</key>
    <string>com.sunsetlakesoftware.molecules.pdb</string>
    <key>UTTypeTagSpecification</key>
    <dict>
        <key>public.filename-extension</key>
        <string>pdb</string>
        <key>public.mime-type</key>
        <string>chemical/x-pdb</string>
    </dict>
</dict>

注意:我为我的应用程序准备了类似的东西,但是在 UTTypeConformsTo 中,我只包含了 public.data,因为我的文件是压缩数据文件。
我发现将 public.text 添加为数组中的第二个项目后,它可以在 iMessage 中使用。另外,如果我添加 public.plain-text 作为第三个项目,我的文件最终会显示 Pages 图标而不是我的图标(因此我将其删除)。
希望这可以帮助某些人。我花了数小时才找到解决方法。

1
我一直无法让这个解决方案起作用。我的设备运行的是iOS 11。这个问题https://stackoverflow.com/q/39709981表明在iOS 10中发生了一些变化。你的应用程序在iOS 11下仍然可以正常打开iMessage附件吗? - user3717478

1
你的Info.plist中LSItemContentTypes键的值应该等于你的Meeting对象声明的值。
假设你的Meeting对象遵循UIActivityItemSource协议。确保你从委托方法activityViewController:dataTypeIdentifierForActivityType:返回的值与你在Info.plist中声明为可读的值相匹配。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接