如何将文件类型与iPhone应用程序关联?


318

关于将iPhone应用程序与文件类型相关联的主题。

这个有用的问题中,我了解到应用程序可以与自定义URL协议相关联。

大约一年前,自那时以来,苹果公司推出了“文档支持”,这进一步向前发展,并允许应用程序与文件类型相关联。文档中有很多关于如何设置您的应用程序以在遇到未知文件类型时启动其他合适的应用程序的话题。这意味着该关联对于任何应用程序都不是开箱即用的,就像URL协议注册一样。

这就引出了一个问题:是否有像Safari或Mail这样的系统应用程序实现了该系统来选择关联的应用程序,还是像以前一样不执行任何操作?

Answers:


408

文件类型处理是iPhone OS 3.2的新增功能,它与现有的自定义URL方案不同。您可以注册您的应用程序以处理特定的文档类型,并且任何使用文档控制器的应用程序都可以将这些文档的处理移交给您自己的应用程序。

例如,如果通过电子邮件或在其他受支持的应用程序中接收到了我的应用程序Molecules(提供源代码),则处理.pdb和.pdb.gz文件类型。

要注册支持,您需要在Info.plist中具有以下内容:

<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeIconFiles</key>
        <array>
            <string>Document-molecules-320.png</string>
            <string>Document-molecules-64.png</string>
        </array>
        <key>CFBundleTypeName</key>
        <string>Molecules Structure File</string>
        <key>CFBundleTypeRole</key>
        <string>Viewer</string>
        <key>LSHandlerRank</key>
        <string>Owner</string>
        <key>LSItemContentTypes</key>
        <array>
            <string>com.sunsetlakesoftware.molecules.pdb</string>
            <string>org.gnu.gnu-zip-archive</string>
        </array>
    </dict>
</array>

提供了两个图像,这些图像将用作Mail和其他能够显示文档的应用程序中受支持类型的图标。该LSItemContentTypes密钥使您可以提供应用程序可以打开的统一类型标识符(UTI)数组。有关系统定义的UTI的列表,请参阅Apple的《统一类型标识符参考》。有关UTI的更多详细信息,请参见Apple的统一类型标识符概述。这些指南位于Mac开发人员中心,因为此功能已从Mac移植过来。

上例中使用的UTI之一是系统定义的,而另一个是特定于应用程序的UTI。需要导出特定于应用程序的UTI,以便可以使系统上的其他应用程序知道它。为此,您可以将以下部分添加到Info.plist中,如下所示:

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

此特定示例导出com.sunsetlakesoftware.molecules.pdb带有.pdb文件扩展名的UTI,对应于MIME类型chemical/x-pdb

使用此功能,您的应用程序将能够处理附加到电子邮件或来自系统上其他应用程序的文档。在邮件中,您可以点击并按住以显示可以打开特定附件的应用程序列表。

打开附件后,您的应用程序将启动,您将需要在-application:didFinishLaunchingWithOptions:应用程序委托方法中处理此文件。看来,以这种方式从Mail加载的文件被复制到应用程序的Documents目录下的子目录中,该子目录对应于它们到达的电子邮件箱。您可以使用以下代码在应用程序委托方法中获取此文件的URL:

NSURL *url = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];

请注意,这与我们用于处理自定义URL方案的方法相同。您可以使用以下代码将文件URL与其他URL分开:

if ([url isFileURL])
{
    // Handle file being passed in
}
else
{
    // Handle custom URL scheme
}

9
应该注意的-application:didFinishLaunchingWithOptions:是,只有在打开应用程序处理文件时未将其后台运行时,才调用应用程序委托。
2011年

3
避免和QuickLook:raywenderlich.com/1980/...
TheLearner

4
我们- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url也应该在iOS 4+上使用
Dmitry

1
键“ CFBundleTypeExtensions”呢?您的代码段似乎没有设置。不需要吗?
布拉姆

3
我已经尝试过这里和其他地方提供的所有方法,但是我仍在努力获取开放的PNG文件。我正在使用iOS7。在某些地方,他们说这个问题始于ios6。是真的吗?我们不能在ios 7的“在以下位置打开”对话框中打开png文件吗?
Kumar Aditya

24

除了Brad的出色回答外,我还发现(至少在iOS 4.2.1上)从Mail应用程序打开自定义文件时,如果以前已打开附件,则不会触发或通知您的应用程序。出现“打开方式为……”弹出窗口,但什么也不做。

这似乎是通过(从)“收件箱”目录中移动文件来解决的。一种安全的方法似乎是在打开文件时(在中)移动(重新)文件-(BOOL)application:openURL:sourceApplication:annotation:,以及遍历Documents / Inbox目录中的文件,删除所有项目,例如applicationDidBecomeActive:。万一先前的导入导致崩溃或中断,则可能需要使用最后一个汇总才能使应用再次处于干净状态。


6
我没有看到这种行为。如果我的应用程序是后台的,-(BOOL)application:openURL:sourceApplication:annotation:则即使已打开的附件也总是被调用。附件每打开一次,文件名就会加上一个数字,并递增为唯一的字符-test.text,test-1.txt,test-2.txt等
。-记忆

我的收件箱目录为空,但是您在Safari中却没有响应的“打开方式”按钮。几年前,我的应用程序运行良好,但突然停止了工作。我怀疑苹果在Safari中做了一些更改。
布拉姆

18

大警告:确保百分之一百确保您的扩展名尚未绑定到某些mime类型。

我们的自定义文件使用扩展名“ .icz”,基本上,而且,Safari永远都不会让您打开它们,说“ Safari无法打开此文件”。无论我们对上面的UT做了什么或尝试过什么。

最终,我意识到可以使用一些UT * C函数来探索各种事物,而.icz给出了正确的答案(我们的应用程序):

在应用程序中确实加载了顶部,只需执行此操作...

NSString * UTI = (NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, 
                                                                   (CFStringRef)@"icz", 
                                                                   NULL);
CFURLRef ur =UTTypeCopyDeclaringBundleURL(UTI);

然后在该行之后插入break,看看UTI和ur是什么-在我们的例子中,这是我们想要的标识符),并且捆绑包网址(ur)指向我们应用的文件夹。

但是Dropbox为我们提供了链接的MIME类型,您可以通过执行以下操作进行检查

$ curl -D headers THEURLGOESHERE > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 27393  100 27393    0     0  24983      0  0:00:01  0:00:01 --:--:-- 28926
$ cat headers
HTTP/1.1 200 OK
accept-ranges: bytes
cache-control: max-age=0
content-disposition: attachment; filename="123.icz"
Content-Type: text/calendar
Date: Fri, 24 May 2013 17:41:28 GMT
etag: 872926d
pragma: public
Server: nginx
x-dropbox-request-id: 13bd327248d90fde
X-RequestId: bf9adc56934eff0bfb68a01d526eba1f
x-server-response-time: 379
Content-Length: 27393
Connection: keep-alive

Content-Type是我们想要的。Dropbox声称这是一个文本/日历条目。大。但就我而言,我已经尝试将文本/日历输入到应用程序的mime类型中,但仍然无法正常工作。相反,当我尝试获取文本/日历模仿类型的UTI和捆绑包网址时,

NSString * UTI = (NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType,
                                                                   (CFStringRef)@"text/calendar", 
                                                                   NULL);

CFURLRef ur =UTTypeCopyDeclaringBundleURL(UTI);

我将“ com.apple.ical.ics”视为UTI,将“ ... / MobileCoreTypes.bundle /”视为捆绑包URL。不是我们的应用程序,而是苹果。因此,我尝试将com.apple.ical.ics和我自己的一起放入LSItemContentTypes,并在导出中放入UTConformsTo,但没有成功。

因此,基本上,如果Apple认为他们希望在某种程度上处理某种形式的文件类型(可以在您的应用上线10年后创建,请注意),您将不得不更改扩展名,因为他们根本不会让您处理文件类型。


感谢您的有用警告!
RockSolid

0

为了为自己的APP处理任何类型的文件,我对CFBundleDocumentTypes使用以下配置:

    <key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeName</key>
            <string>IPA</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.item</string>
                <string>public.content</string>
                <string>public.data</string>
                <string>public.database</string>
                <string>public.composite-content</string>
                <string>public.contact</string>
                <string>public.archive</string>
                <string>public.url-name</string>
                <string>public.text</string>
                <string>public.plain-text</string>
                <string>public.source-code</string>
                <string>public.executable</string>
                <string>public.script</string>
                <string>public.shell-script</string>
                <string>public.xml</string>
                <string>public.symlink</string>
                <string>org.gnu.gnu-zip-archve</string>
                <string>org.gnu.gnu-tar-archive</string>
                <string>public.image</string>
                <string>public.movie</string>
                <string>public.audiovisual-​content</string>
                <string>public.audio</string>
                <string>public.directory</string>
                <string>public.folder</string>
                <string>com.apple.bundle</string>
                <string>com.apple.package</string>
                <string>com.apple.plugin</string>
                <string>com.apple.application-​bundle</string>
                <string>com.pkware.zip-archive</string>
                <string>public.filename-extension</string>
                <string>public.mime-type</string>
                <string>com.apple.ostype</string>
                <string>com.apple.nspboard-typ</string>
                <string>com.adobe.pdf</string>
                <string>com.adobe.postscript</string>
                <string>com.adobe.encapsulated-​postscript</string>
                <string>com.adobe.photoshop-​image</string>
                <string>com.adobe.illustrator.ai-​image</string>
                <string>com.compuserve.gif</string>
                <string>com.microsoft.word.doc</string>
                <string>com.microsoft.excel.xls</string>
                <string>com.microsoft.powerpoint.​ppt</string>
                <string>com.microsoft.waveform-​audio</string>
                <string>com.microsoft.advanced-​systems-format</string>
                <string>com.microsoft.advanced-​stream-redirector</string>
                <string>com.microsoft.windows-​media-wmv</string>
                <string>com.microsoft.windows-​media-wmp</string>
                <string>com.microsoft.windows-​media-wma</string>
                <string>com.apple.keynote.key</string>
                <string>com.apple.keynote.kth</string>
                <string>com.truevision.tga-image</string>
            </array>
            <key>CFBundleTypeIconFiles</key>
            <array>
                <string>Icon-76@2x</string>
            </array>
        </dict>
    </array>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.