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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2774343/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:11:42  来源:igfitidea点击:

How do I associate file types with an iPhone application?

ioscocoa-touch

提问by Mihai Damian

On the subject of associating your iPhone app with file types.

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

In thisinformative question I learned that apps could be associated with custom URL protocols.

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

That was almost one year ago and since then Apple introduced 'Document Support' which goes a step further and allows apps to associate with file types. There is a lot of talk in the documentationabout how to set up your app to launch other appropriate apps when it encounters an unknown file type. This means the association doesn't work out of the box for any app, like the URL protocol registering did.

那是大约一年前,从那时起 Apple 推出了“文档支持”,它更进了一步,允许应用程序与文件类型相关联。文档中有很多关于如何设置您的应用程序以在遇到未知文件类型时启动其他适当应用程序的讨论。这意味着关联对于任何应用程序都不是开箱即用的,就像 URL 协议注册所做的那样。

This leads me to the question: have system apps like Safari or Mail implemented this system for choosing associated applications, or will they do nothing, as before?

这让我产生了一个问题:Safari 或 Mail 等系统应用程序是否实现了这个系统来选择关联的应用程序,或者它们会像以前一样什么都不做?

回答by Brad Larson

File type handling is new with iPhone OS 3.2, and is different than the already-existing custom URL schemes. You can register your application to handle particular document types, and any application that uses a document controller can hand off processing of these documents to your own application.

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

For example, my application Molecules(for which the source code is available) handles the .pdb and .pdb.gz file types, if received via email or in another supported application.

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

To register support, you will need to have something like the following in your Info.plist:

要注册支持,您需要在 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>

Two images are provided that will be used as icons for the supported types in Mail and other applications capable of showing documents. The LSItemContentTypeskey lets you provide an array of Uniform Type Identifiers (UTIs) that your application can open. For a list of system-defined UTIs, see Apple's Uniform Type Identifiers Reference. Even more detail on UTIs can be found in Apple's Uniform Type Identifiers Overview. Those guides reside in the Mac developer center, because this capability has been ported across from the Mac.

提供了两张图像,它们将用作邮件和其他能够显示文档的应用程序中受支持类型的图标。该LSItemContentTypes键可让您提供应用程序可以打开的一组统一类型标识符 (UTI)。有关系统定义的 UTI 列表,请参阅 Apple 的统一类型标识符参考。更多关于 UTI 的细节可以在 Apple 的Uniform Type Identifiers Overview 中找到。这些指南位于 Mac 开发人员中心,因为此功能已从 Mac 移植过来。

One of the UTIs used in the above example was system-defined, but the other was an application-specific UTI. The application-specific UTI will need to be exported so that other applications on the system can be made aware of it. To do this, you would add a section to your Info.plist like the following:

上面示例中使用的 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>

This particular example exports the com.sunsetlakesoftware.molecules.pdbUTI with the .pdb file extension, corresponding to the MIME type chemical/x-pdb.

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

With this in place, your application will be able to handle documents attached to emails or from other applications on the system. In Mail, you can tap-and-hold to bring up a list of applications that can open a particular attachment.

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

When the attachment is opened, your application will be started and you will need to handle the processing of this file in your -application:didFinishLaunchingWithOptions:application delegate method. It appears that files loaded in this manner from Mail are copied into your application's Documents directory under a subdirectory corresponding to what email box they arrived in. You can get the URL for this file within the application delegate method using code like the following:

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

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

Note that this is the same approach we used for handling custom URL schemes. You can separate the file URLs from others by using code like the following:

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

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

回答by mvds

In addition to Brad's excellent answer, I have found out that (on iOS 4.2.1 at least) when opening custom files from the Mail app, your app is not fired or notified if the attachment has been opened before. The "open with…" popup appears, but just does nothing.

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

This seems to be fixed by (re)moving the file from the Inbox directory. A safe approach seems to be to both (re)move the file as it is opened (in -(BOOL)application:openURL:sourceApplication:annotation:) as well as going through the Documents/Inbox directory, removing all items, e.g. in applicationDidBecomeActive:. That last catch-all may be needed to get the app in a clean state again, in case a previous import causes a crash or is interrupted.

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

回答by Kalle

BIG WARNING: Make ONE HUNDRED PERCENT sure that your extension is not already tied to some mime type.

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

We used the extension '.icz' for our custom files for, basically, ever, and Safari just never would let you open them saying "Safari cannot open this file." no matter what we did or tried with the UT stuff above.

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

Eventually I realized that there are some UT* C functions you can use to explore various things, and while .icz gives the right answer (our app):

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

In app did load at top, just do this...

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

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

and put break after that line and see what UTI and ur are -- in our case, it was our identifier as we wanted), and the bundle url (ur) was pointing to our app's folder.

并在该行之后放置 break 并查看 UTI 和 ur 是什么——在我们的例子中,它是我们想要的标识符),并且包 url (ur) 指向我们应用程序的文件夹。

But the MIME type that Dropbox gives us back for our link, which you can check by doing e.g.

但是 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

The Content-Type is what we want. Dropbox claims this is a text/calendar entry. Great. But in my case, I've ALREADY TRIED PUTTING text/calendar into my app's mime types, and it still doesn't work. Instead, when I try to get the UTI and bundle url for the text/calendar mimetype,

Content-Type 是我们想要的。Dropbox 声称这是一个文本/日历条目。伟大的。但就我而言,我已经尝试将文本/日历放入我的应用程序的 mime 类型中,但它仍然不起作用。相反,当我尝试获取文本/日历 mimetype 的 UTI 和捆绑 URL 时,

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

CFURLRef ur =UTTypeCopyDeclaringBundleURL(UTI);

I see "com.apple.ical.ics" as the UTI and ".../MobileCoreTypes.bundle/" as the bundle URL. Not our app, but Apple. So I try putting com.apple.ical.ics into the LSItemContentTypes alongside my own, and into UTConformsTo in the export, but no go.

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

So basically, if Apple thinks they want to at some point handle some form of file type (that could be created 10 years after your app is live, mind you), you will have to change extension cause they'll simply not let you handle the file type.

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

回答by SLdragon

To deal with any type of files for my own APP, I use this configuration for CFBundleDocumentTypes:

为了处理我自己的 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>