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

时间:2021-07-04 07:26:04

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

关于把你的iPhone应用和文件类型联系起来的话题。

In this informative 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 documentation about 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.

那差不多是一年前的事了,从那以后,苹果推出了“文档支持”(Document Support),这一功能更进一步,允许应用程序与文件类型关联。在文档中有很多关于如何设置应用程序以在遇到未知文件类型时启动其他适当应用程序的讨论。这意味着关联对于任何应用程序都不是开箱即用的,就像注册的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这样的系统应用程序实现了这个系统来选择相关的应用程序,或者它们会像以前一样什么都不做吗?

3 个解决方案

#1


395  

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 LSItemContentTypes key 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键允许您提供应用程序可以打开的统一类型标识符数组。有关系统定义的UTIs的列表,请参见苹果的统一类型标识符引用。关于UTIs的更多细节可以在苹果的统一类型标识符概述中找到。这些指南位于Mac developer center中,因为这个功能是从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:

上面示例中使用的一个UTIs是系统定义的,但是另一个是特定于应用程序的UTI。特定于应用程序的UTI需要被导出,以便系统上的其他应用程序能够意识到它。要做到这一点,你需要在你的信息中添加一个章节。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.pdb UTI with the .pdb file extension, corresponding to the MIME type chemical/x-pdb.

这个特殊的例子输出com. sunsetlakesoftwaree . molecular。带.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: application delegate方法中处理这个文件的处理。看起来,以这种方式从邮件中加载的文件会被复制到应用程序的文档目录下的子目录中,该子目录对应于它们到达的邮箱。您可以使用以下代码在application delegate方法中获取该文件的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
}

#2


22  

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出色的回答外,我还发现(至少在ios4.2.1中)在打开邮件应用的自定义文件时,您的应用程序不会被解除,也不会被通知附件是否已被打开。“open with…”弹出,但什么都不做。

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.

这似乎是通过将文件从Inbox目录移动来修复的。一种安全的方法似乎是在打开文件时(重新)移动文件(在-(BOOL)应用程序中:openURL:sourceApplication:annotation:),并通过document /Inbox目录,删除所有项,例如application didbecomeactive:。最后一种方法可能需要在干净的状态下重新获得应用程序,以防之前的导入导致崩溃或被中断。

#3


16  

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

大警告:100%确保您的扩展没有绑定到某些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给出了正确的答案(我们的app):

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

在app中,加载在顶部,就这么做…

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是什么,在我们的例子中,它是我们想要的标识符,bundle url (ur)指向我们的app文件夹。

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,

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

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“as the UTI and”…/MobileCoreTypes。bundle/"作为bundle URL。不是我们的应用,而是苹果。所以我试着写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.

因此,基本上,如果苹果认为他们想在某个时候处理某种形式的文件类型(注意,这可以在你的应用程序上线10年后创建),你必须改变扩展名,因为他们不会让你处理文件类型。

#1


395  

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 LSItemContentTypes key 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键允许您提供应用程序可以打开的统一类型标识符数组。有关系统定义的UTIs的列表,请参见苹果的统一类型标识符引用。关于UTIs的更多细节可以在苹果的统一类型标识符概述中找到。这些指南位于Mac developer center中,因为这个功能是从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:

上面示例中使用的一个UTIs是系统定义的,但是另一个是特定于应用程序的UTI。特定于应用程序的UTI需要被导出,以便系统上的其他应用程序能够意识到它。要做到这一点,你需要在你的信息中添加一个章节。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.pdb UTI with the .pdb file extension, corresponding to the MIME type chemical/x-pdb.

这个特殊的例子输出com. sunsetlakesoftwaree . molecular。带.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: application delegate方法中处理这个文件的处理。看起来,以这种方式从邮件中加载的文件会被复制到应用程序的文档目录下的子目录中,该子目录对应于它们到达的邮箱。您可以使用以下代码在application delegate方法中获取该文件的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
}

#2


22  

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出色的回答外,我还发现(至少在ios4.2.1中)在打开邮件应用的自定义文件时,您的应用程序不会被解除,也不会被通知附件是否已被打开。“open with…”弹出,但什么都不做。

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.

这似乎是通过将文件从Inbox目录移动来修复的。一种安全的方法似乎是在打开文件时(重新)移动文件(在-(BOOL)应用程序中:openURL:sourceApplication:annotation:),并通过document /Inbox目录,删除所有项,例如application didbecomeactive:。最后一种方法可能需要在干净的状态下重新获得应用程序,以防之前的导入导致崩溃或被中断。

#3


16  

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

大警告:100%确保您的扩展没有绑定到某些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给出了正确的答案(我们的app):

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

在app中,加载在顶部,就这么做…

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是什么,在我们的例子中,它是我们想要的标识符,bundle url (ur)指向我们的app文件夹。

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,

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

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“as the UTI and”…/MobileCoreTypes。bundle/"作为bundle URL。不是我们的应用,而是苹果。所以我试着写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.

因此,基本上,如果苹果认为他们想在某个时候处理某种形式的文件类型(注意,这可以在你的应用程序上线10年后创建),你必须改变扩展名,因为他们不会让你处理文件类型。