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

在关联您的iPhone应用程序与文件types的主题。

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

这大概是一年前,从那以后,苹果推出了“文档支持”,它进一步推动了应用程序与文件types的关联。 有关如何设置您的应用程序以在遇到未知文件types时启动其他适当的应用程序的文档中有很多讨论。 这意味着该协会不适用于任何应用程序,就像URL协议注册一样。

这使我想到了这样一个问题:像Safari或Mail这样的系统应用程序是否实现了这个系统来select关联的应用程序,还是像以前一样不做任何事情?

文件types处理是iPhone OS 3.2的新增function,与已有的自定义URLscheme不同。 您可以注册您的应用程序来处理特定的文档types,任何使用文档控制器的应用程序都可以将这些文档的处理交给您自己的应用程序。

例如,如果通过电子邮件或其他支持的应用程序接收到我的应用程序Molecules (源代码可用),它将处理.pdb和.pdb.gz文件types。

要注册支持,您需要在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和其他能够显示文档的应用程序中受支持types的图标。 LSItemContentTypes键允许您提供应用程序可以打开的统一types标识符(UTI)数组。 有关系统定义的UTI列表,请参阅Apple的统一types标识符参考 。 关于UTI的更多细节可以在苹果统一types标识符概述中find 。 这些指南驻留在Mac开发人员中心,因为此function已从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 UTI与.pdb文件扩展名相对应的MIMEtypeschemical/x-pdb

有了这个,您的应用程序将能够处理附加到电子邮件或从系统上的其他应用程序的文件。 在Mail中,您可以点击并按住以打开可打开特定附件的应用程序列表。

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

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

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

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

除了Brad的出色答案之外,我发现(在iOS 4.2.1中)从Mail应用程序打开自定义文件时,如果之前打开了附件,则不会触发或通知您的应用程序。 出现“打开…”popup窗口,但是什么都不做。

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

大警告:百分百确保你的分机还没有被绑定到某种MIMEtypes。

我们使用扩展名'.icz'作为自定义文件,基本上,Safari永远不会让你打开“Safari无法打开这个文件”。 不pipe我们做了什么或者尝试过UT的东西。

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

在应用程序确实加载在顶部,只是这样做…

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

并在该行后面打破,看看UTI和你是什么 – 在我们的例子中,它是我们想要的标识符),并且bundle url(ur)指向我们应用程序的文件夹。

但是Dropbox为我们的链接提供的MIMEtypes,您可以通过这种方式进行检查

 $ 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 

内容types是我们想要的。 Dropbox声称这是一个文本/日历条目。 大。 但在我的情况下,我已经试图将文本/日历放入我的应用程序的MIMEtypes,它仍然无法正常工作。 相反,当我尝试获取文本/日历mimetype的UTI和捆绑url时,

 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中,但是不行。

所以基本上,如果苹果认为他们想在某种程度上处理某种forms的文件types(可能会在您的应用程序生效10年后创build),那么您将不得不改变扩展名的原因,他们将不会让您处理文件types。