前言
项目要加个附件功能,要求发布者能添加word、pdf什么的,查看者能下载并预览。
安卓端表示OK无问题。iOS端表示w*%#~c。由于沙盒机制,没越狱的iPhone不同App文件都是不互通的。
骂归骂,这个功能起码不像根据手机壳颜色更改App主题颜色一样天方夜谭。还是能想想怎么实现的。
下载没难度;预览很多库都有接口;上传功能也不难。难就难在上传的这个文件怎么来。
总不能像WPS Office那样写一套底层实现吧。就算实现了,软件大小变大了不说,又有多少个人会在手机上编辑office文件呢?吃力不讨好,还是想想怎么转发别的地方的Office文件吧。
理性分析一波,工作上,编辑这些事通常都是放在电脑上做的,然后通过电脑端QQ、微信、email发送到手机。实质就是上传到服务器,在手机端从服务器里下载下来。从而实现了App里获取到该文件。
但我们这些App哪有什么电脑端发送到手机功能。总不能开发个电脑端,专门给用户把文件上传到服务器。
大家也已经习惯了工作上的office文件通过QQ、微信、email转到手机上看。
于是乎,反正先从电脑发到手机,那再分享到该App也能间接实现。
为了方便在模拟器测试,查看沙盒文件状态,弄了个演示预览文件功能,还能分享到别的App的软件。
在这向原作者表达感谢。
首先在App里注册支持的文件类型。
这一步是为了点分享时,App能显示在分享列表中。
- 添加苹果有的已知格式
打开Info.plist文件,添加以下内容。
Document types:支持类型的数组,装着各个分组item。Document Type Name:分组名。随便设置也没所谓。简单点说就是要不要分文件夹管理。我分成了Office和PDF。合在一起功能也是一样的。Handler rank:排列顺序优先级。Owner、Default、Alternate。None不显示。Document Content Type UTIs:文件类型的UTI。格式对应的标识符。苹果规定了一些格式对应的标识符,链接在下,可查看。还可以设置分享列表的图标,不设置默认用APP的图标。这里就不深入了。复制代码
针对本文,支持的office文件格式仅有doc、xls、ppt。
但没有规定xlsx等新版的拓展名,要怎么才能支持xlsx呢?
- 添加自定义格式标识符
第一步 在Info.plist中加入以下内容。
Identifier:唯一标识符,填App的Bundle Identifier加个名字。Equivalent Types:在这加入扩展名。复制代码
第二步 和以上差不多
至于其他doct步骤相同就不贴出来了。
注册支持的文件类型到这就完成了。
分享后在App内拿到文件
从别的App跳进目的App就会调用这方法。
iOS 9.0后的版本
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options;复制代码
iOS 9.0之前的版本
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation;复制代码
要注意的是,要根据url判断发生的是什么事。
if ([url.host isEqualToString:@"safepay"]) { //跳转支付宝钱包进行支付,处理支付结果 [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { NSLog(@"result = %@",resultDic); }]; }else if ([url.host isEqualToString:@"pay"]){//微信支付 return [WXApi handleOpenURL:url delegate:self]; }else if([url.host isEqualToString:@"oauth"]){//微信登陆 return [WXApi handleOpenURL:url delegate:self]; }else if([url.host isEqualToString:@"qzapp"]){//QQ登陆 [QQApiInterface handleOpenURL:url delegate:self]; return [TencentOAuth HandleOpenURL:url]; } else { //回调处理文件 UIAlertController *alertCtl = [UIAlertController alertControllerWithTitle:@"保存文件成功" message:nil preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *action = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil]; [alertCtl addAction:action]; [self.window.rootViewController presentViewController:alertCtl animated:YES completion:nil]; [[NSNotificationCenter defaultCenter] postNotificationName:@"configFilesArray" object:nil]; return YES; }复制代码
可惜的是,文件分享回调url.host = nil
。我只能把它放在最后的情况中了。希望有大神告知怎么区别出来。
当跳进目的App这个方法时,文件已经拷贝到/Documents/Inbox
目录下了。如果有重名,文件名最后会自动增加"-1"、"-2"。
要拿到文件名就打[url.path lastPathComponent]
。
到这里就完成了文件的获取。
特意做了个文件管理工具。
之前没怎么用过NSFileManager真的是研究了两天。
其包括了
获取文件列表(按创建时间排序):方便在tableView中显示出来。 这一步真的恶心。
遍历文件夹只能拿到文件名字。
用文件名获取属性返回字典又没有了文件名。
删除文件:删除文件是为了清理存储空间,因为分享的文件不会自动清除。
预览
- 方法一 用UIWebView展示。只要把文件路径传进去就能用
_webView = [[UIWebView alloc]initWithFrame:self.view.bounds]; _webView.delegate = self; NSURLRequest *request = [NSURLRequest requestWithURL:self.url]; [_webView loadRequest:request]; [_webView setScalesPageToFit:YES]; [self.view addSubview:_webView];复制代码
- 方法二(推荐,自带分享功能) 用<QuickLook/QuickLook.h>。该方法使用比上一个稍微复杂,但好处是能点击分享。如果用户觉得辛苦,可以换到WPS浏览。