Document Interaction是为你的app提供把文件传输给其它app和接收其它app传来的文件的功能,网上的Document Interaction教程都是比较老的,为此附上2016最新Document Interaction教程。
注册应用程序支持的文件类型
打开项目的info.plist文件,在其中加上
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>wzzyinqiang.guangyao-s-data</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>com.microsoft.powerpoint.ppt</string>
<string>public.item</string>
<string>com.microsoft.word.doc</string>
<string>com.adobe.pdf</string>
<string>com.microsoft.excel.xls</string>
<string>public.image</string>
<string>public.content</string>
<string>public.composite-content</string>
<string>public.archive</string>
<string>public.audio</string>
<string>public.movie</string>
<string>public.text</string>
<string>public.data</string>
</array>
</dict>
</array>
这其中有不少配置属性,一个一个讲解。
CFBundleDocumentTypes这是一个主属性,它代表你的app有着多种CFBundleTypeName,每种CFBundleTypeName有一个名字。
LSHandlerRank这是另一个属性,它代表你的app接收到文件后是保存到沙盒还是其它的处理方式,Owner是保存到沙盒,这里我推荐大家就用Owner就可以了。(注意一定要是Owner,网上有的资料是owner,首字母如果没有大写,在上传ipa时会报ERROR ITMS-90151的错误,当时这个问题纠结了我好久……)
LSItemContentTypes这是你所支持的文件类型属性,可以看到下面是一个array,其中有不少的文件类型,这里大家直接复制上面的就好,它包含了大部分的文件类型。
如何监测你的app收到了文件?
如果你的app处于挂起状态,并以“其它应用打开”这种方式重新激活了你的app,那么你可以在
- (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(nullableNSString*)sourceApplication annotation:(id)annotation
这个函数中来接收到该文件的url,用调用函数[NSData dataWithContentsOfURL:url]获取到这个文件的data就可以对它操作了。
如果你的app根本没有被打开,那么你可以在启动函数
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
调用[launchOptions[UIApplicationLaunchOptionsURLKey]即可获取到这个文件的url了。
创建并呈现DocumentInteraction Controller
self.documentController= [UIDocumentInteractionControllerinteractionControllerWithURL:[NSURLfileURLWithPath:self.file_path]];
[self.documentControllerpresentOpenInMenuFromRect:CGRectZeroinView:self.viewanimated:YES];
self是当前的vc。
这里把documentController作为成员变量是因为如果你把documentController作为局部变量来创建和使用,在presentOpenInMenuFromRect函数调用后该局部变量就会被销毁,因为已经没有指针指向它了,不知道这是不是一个官方bug,也可能是因为arc的问题,总之把它设置为成员变量是最简单直接的解决办法。
上面两条代码会造成短暂的卡顿,推荐把第一条代码放到子线程。