关于将iPhone应用程序与文件类型关联的主题。
在这个信息丰富的问题中,我了解到应用程序可以与自定义URL协议相关联。
大约一年前,苹果推出了“文档支持”,允许应用程序与文件类型关联。文档中有很多关于如何设置你的应用在遇到未知文件类型时启动其他适当的应用的讨论。这意味着关联不会像URL协议注册那样,对任何应用程序开箱即用。
这就引出了一个问题:像Safari或Mail这样的系统应用程序是否实现了这个选择相关应用程序的系统,还是像以前一样什么都不做?
关于将iPhone应用程序与文件类型关联的主题。
在这个信息丰富的问题中,我了解到应用程序可以与自定义URL协议相关联。
大约一年前,苹果推出了“文档支持”,允许应用程序与文件类型关联。文档中有很多关于如何设置你的应用在遇到未知文件类型时启动其他适当的应用的讨论。这意味着关联不会像URL协议注册那样,对任何应用程序开箱即用。
这就引出了一个问题:像Safari或Mail这样的系统应用程序是否实现了这个选择相关应用程序的系统,还是像以前一样什么都不做?
文件类型处理是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>
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.
上面示例中使用的一个UTI是系统定义的,但另一个是特定于应用程序的UTI。需要导出特定于应用程序的UTI,以便系统上的其他应用程序可以知道它。要做到这一点,您需要在Info中添加一个部分。请像下面这样写:
<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.com molecules.pdb UTI和.pdb文件扩展名,对应于MIME类型chemical/x-pdb。
有了这些,您的应用程序将能够处理附加到电子邮件或系统上其他应用程序的文档。在Mail中,您可以长按打开一个可以打开特定附件的应用程序列表。
当打开附件时,您的应用程序将被启动,您将需要在您的-application:didFinishLaunchingWithOptions: application delegate方法中处理此文件的处理。以这种方式从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
}
除了Brad的精彩回答之外,我还发现(至少在iOS 4.2.1上)当从邮件应用程序打开自定义文件时,如果附件之前已被打开,应用程序不会被触发或通知。“用…打开”弹出框出现,但什么也不做。
这似乎可以通过(重新)从收件箱目录移动文件来解决。一个安全的方法似乎是(重新)移动文件,因为它被打开(在-(BOOL)application:openURL:sourceApplication:annotation:),以及通过文档/收件箱目录,删除所有的项目,例如在applicationDidBecomeActive:。为了防止之前的导入导致崩溃或中断,可能需要使用最后的catch-all使应用程序再次处于干净状态。
大警告:请百分之百确定您的扩展没有绑定到某个mime类型。
我们使用了扩展名'。icz'用于我们的自定义文件,基本上,永远,Safari不会让你打开它们说"Safari无法打开这个文件"不管我们用上面的UT做了什么或尝试了什么。
最终,我意识到有一些UT* C函数可以用来探索各种东西,而.icz给出了正确的答案(我们的应用程序):
在app did load at top中,只需要这样做…
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
Content-Type就是我们想要的。Dropbox声称这是一个文本/日历条目。太好了。但在我的情况下,我已经尝试把文本/日历放入我的应用程序的mime类型,它仍然不工作。相反,当我试图获得文本/日历mimetype的UTI和捆绑url时,
NSString * UTI = (NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType,
(CFStringRef)@"text/calendar",
NULL);
CFURLRef ur =UTTypeCopyDeclaringBundleURL(UTI);
我看到“com.apple.ical”。作为UTI和…/MobileCoreTypes. ics。bundle/"作为bundle URL。不是我们的应用,而是苹果。所以我试着把com.apple.ical.ics和我自己的放在LSItemContentTypes中,并在导出中放入UTConformsTo,但没有成功。
所以基本上,如果苹果认为他们想要在某个时候处理某种形式的文件类型(注意,这可能是在你的应用程序发布10年后创建的),你将不得不改变扩展名,因为他们不会让你处理文件类型。
为了处理我自己的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>
安装duti。它是立即将uti绑定到Appls的最完整和最严肃的解决方案。这里有:GitHub上的duti
如果你喜欢图形界面:SwiftDefaultApps在GitHub