iOS通过UTI(统一类型标示符)实现应用间文件的传递

最近需要实现一个应用内导入excel文件的需求,突然想到了在使用其他应用的分享时都会看到下边有几个第三方应用。

logo

那我们就来看看这个功能是如何实现的。

另外,这篇文章写之前有学习并参考了SeraZheng大神在简书上的详解苹果提供的UTI(统一类型标识符)。关于UTI的详细解析也可以参考大神的文章,如侵权的部分我会删掉。

##什么是 UTI

UTI全拼Uniform Type Identifier,直接翻译过来就是统一类型标示符。

那UTI究竟有什么用处呢?它是作为一个应用之间的桥梁,比如现在世界上大部分人都会说英语,那一个中国人到法国去,法国人说的是法语,两个人没办法沟通怎么办?这时候会英语就变得很重要,UTI就是这个作用。

如何实现?

注册文档可识别类型

首先我们先在info.plist中添加如下字段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>LSItemContentTypes</key>
<array>
<string>public.data</string>
<string>public.image</string>
</array>
<key>CFBundleTypeIconFiles</key>
<array>
<string>Group.png</string>
</array>
<key>CFBundleTypeName</key>
<string>public.image</string>
<key>LSHandlerRank</key>
<string>Owner</string>
</dict>
</array>

在Xcode中看就是这样的:

logo

我来解释一下每个字段的意思:

  • CFBundleDocumentTypes(Document types)
    代表我们支持的文件类型,这是一个数组类型的字段,所以意味着我们可以添加多种文件类型。文件类型列表可以在官方文档中查看:Core Foundation Keys - CFBundleDocumentTypes

  • LSItemContentTypes (Document Content Type UTIs)
    通过使用UTI字符串来确定我们可以识别的类型。查看所有的类型也可以子啊官方文档中查看:System-Declared Uniform Type Identifiers

  • CFBundleTypeIconFiles (CFBundleTypeIconFiles)
    显示在AirDrop下的图标。尺寸如下:

    logo
  • CFBundleTypeName (Document Type Name)
    字符串类型,代表这个文档类型的名字。

  • LSHandlerRank (Handler rank)
    提供四种可选参数:OwnerAlertnateDefaultNone,制定对于某种类型的优先权级别,级别从左到右由高到低,最后一种None表示不接受此类型。

完成了以上的操作之后我们可以看到TARGETS -> Info -> Document Types中会变成这个样子:

logo

回调操作

实现以上配置之后,我们就可以在第三方应用(比如QQ)中看到点击“用其他应用打开”下我们应用的名字和图标了。那么在回调到我们应用之后要怎么操作呢?

我们需要在AppDelegate中的openURL函数中实现

1
2
3
4
5
6
7
8
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
NSLog(@"%@",[options objectForKey:UIApplicationOpenURLOptionsSourceApplicationKey]);
[self.mainVC setUpContentWithInfo:url];
return YES;
}

但是这个函数只支持iOS 9及以上的系统,一下的系统可以使用这个方法代替:

1
2
3
4
5
6
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation
{
[self.mainVC setUpContentWithInfo:url];
return YES;
}

Demo

至此我们实现应用间文件传递的需求就实现了,Demo地址在这里