iOS 打破沙盒限制 处理其他App的Office等文件(上传、下载、预览)

前言

项目要加个附件功能,要求发布者能添加word、pdf什么的,查看者能下载并预览。

安卓端表示OK无问题。iOS端表示w*%#~c。由于沙盒机制,没越狱的iPhone不同App文件都是不互通的。

骂归骂,这个功能起码不像根据手机壳颜色更改App主题颜色一样天方夜谭。还是能想想怎么实现的。

下载没难度;预览很多库都有接口;上传功能也不难。难就难在上传的这个文件怎么来。

总不能像WPS Office那样写一套底层实现吧。就算实现了,软件大小变大了不说,又有多少个人会在手机上编辑office文件呢?吃力不讨好,还是想想怎么转发别的地方的Office文件吧。

理性分析一波,工作上,编辑这些事通常都是放在电脑上做的,然后通过电脑端QQ、微信、email发送到手机。实质就是上传到服务器,在手机端从服务器里下载下来。从而实现了App里获取到该文件。

但我们这些App哪有什么电脑端发送到手机功能。总不能开发个电脑端,专门给用户把文件上传到服务器。

大家也已经习惯了工作上的office文件通过QQ、微信、email转到手机上看。

于是乎,反正先从电脑发到手机,那再分享到该App也能间接实现。


本文代码在这里

为了方便在模拟器测试,查看沙盒文件状态,弄了个演示预览文件功能,还能分享到别的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<UIApplicationOpenURLOptionsKey,id> *)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浏览。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值