代码之家  ›  专栏  ›  技术社区  ›  Mihai Damian

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

  •  314
  • Mihai Damian  · 技术社区  · 14 年前

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

    this 我了解到应用程序可以与自定义url协议相关联。

    这是一年前的事了,从那时起,苹果公司推出了“文档支持”,这一技术更进一步,允许应用程序与文件类型相关联。有很多人在谈论 documentation 关于如何设置应用程序以在遇到未知文件类型时启动其他相应的应用程序。这意味着关联对于任何应用程序都不是现成的,就像url协议注册那样。

    这就引出了一个问题:像safari或mail这样的系统应用程序是否已经实现了这个系统来选择相关的应用程序,或者他们会像以前一样什么也不做?

    3 回复  |  直到 8 年前
        1
  •  399
  •   BoltClock    12 年前

    文件类型处理是iPhoneOS3.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>
    

    提供了两个图像,用作邮件和其他能够显示文档的应用程序中支持类型的图标。这个 LSItemContentTypes 键允许您提供应用程序可以打开的统一类型标识符(utis)数组。有关系统定义的utis的列表,请参见Apple的 Uniform Type Identifiers Reference . 苹果公司的 Uniform Type Identifiers Overview . 这些指南位于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: 应用程序委托方法。以这种方式从邮件加载的文件似乎被复制到应用程序的文档目录下的子目录中,该子目录对应于它们到达的电子邮件框。可以使用如下代码在应用程序委托方法中获取此文件的url:

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

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

    if ([url isFileURL])
    {
        // Handle file being passed in
    }
    else
    {
        // Handle custom URL scheme
    }
    
        2
  •  23
  •   Community CDub    8 年前

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

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

        3
  •  16
  •   Kalle    11 年前

    大警告:100%确保你的扩展没有绑定到某个mime类型。

    我们使用扩展名“.icz”作为自定义文件的扩展名,基本上是永久的,safari永远不会让你打开它们,说“safari不能打开这个文件”。无论我们做了什么,或者尝试了上面的ut内容。

    最后我意识到有些ut*c函数可以用来探索各种各样的东西,而.icz给出了正确的答案(我们的应用程序):

    应用程序加载在顶部,只需这样做…

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

    在这行后面加上break,看看uti和ur是什么——在我们的例子中,它是我们想要的标识符),bundle url(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
    

    内容类型是我们想要的。Dropbox声称这是一个文本/日历条目。伟大的。但在我的例子中,我已经尝试过将文本/日历放入我的应用程序的mime类型中,但仍然不起作用。相反,当我试图获取文本/日历mimetype的uti和bundle url时,

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

    我将“com.apple.ical.ics”作为uti,将“../mobilecoretypes.bundle/”作为bundle url。不是我们的应用,而是苹果。因此,我尝试将com.apple.ical.ics与我自己的内容类型一起放入lsitemcontenttypes,并在导出中放入utconformsto,但不执行。

    所以基本上,如果苹果认为他们想在某个时候处理某种形式的文件类型(注意,这可能是在你的应用程序运行10年后创建的),你就必须更改扩展名,因为他们根本不允许你处理文件类型。