UIDocumentInteractionController之程序间文档共享

iOS中的沙盒可以让平台更加的安全,这也是沙盒给用户带来的最主要好处。不过由于沙盒的严格限制,导致程序之间共享数据比较麻烦。一般在程序间共享文档可以通过UIDocumentInteractionController类实现通讯。它支持在你的app中用其他app预览和显示文档。同时也支持文件关联,允许其他app通过你的程序打开文件。这些技术包括了UIKit中提供的UIDocumentInteractionController类(UIDocumentInteractionController Class Reference),以及Quick Look框架(Quick Look Framework Reference)。

本文将就如何在应用之间进行文件共享进行基本探究。还请大牛勿喷。

苹果官方文档

效果图

文件共享

跨APP傳文件

预览文档和呈现选项菜单

如果你的app需要打开它不支持的文件(PDF文件、图像文件,等等),或者需要将app的文件传输给另外一个允许接收此类型文件的app时。可以使用文件交互控制器(UIDocumentInteractionController类的实例)为用户提供可接收程序来处理文件,说的简单点就是通过Quick Look框架判断文档是否能被另一个app打开和预览。

UIDocumentInteractionController在iOS3.2中就已经存在了,使用起来非常灵活,功能也比较强大。它除了支持同设备上app之间的文档共享外,还可以实现文档的预览、打印、发邮件以及复制。

要使用一个文件交互控制器(UIDocumentInteractionController类的实例),需要以下步骤:

  1. 为每个你想打开的文件创建一个UIDocumentInteractionController类的实例
  2. 实现UIDocumentInteractionControllerDelegate代理
  3. 显示预览窗口/显示菜单。

一、创建实例

DocumentInteraction Controller使用静态方法interactionControllerWithURL创建实例,这个方法使用一个NSURL作为参数。

//创建实例
NSURL *filePath = [NSURL fileURLWithPath:path];UIDocumentInteractionController *documentController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];

二、显示预览窗口

Document Interaction Controller对象使用presentPreviewAnimated方法弹出一个全屏的文档预览窗口。

BOOL b = [documentController presentPreviewAnimated:YES];

三、显示菜单

如果你不想在本应用里面打开文件,那么可以通过第三方应用打开预览文件。通过OptionsMenu(选项菜单),显示能够接收该类型文件的应用,由用户选择相应的操作。

显示菜单可以使用下列方法:

- presentOptionsMenuFromRect:inView:animated:
- presentOptionsMenuFromBarButtonItem:animated:
- presentOpenInMenuFromRect:inView:animated:
- presentOpenInMenuFromBarButtonItem:animated:

这些方法都是类似的,只是显示位置有区别而已。以下代码演示其中一个方法的使用。

CGRect navRect = self.navigationController.navigationBar.frame;
navRect.size = CGSizeMake(1500.0f, 40.0f);
[documentController presentOptionsMenuFromRect:navRectinView:self.viewanimated:YES];

四、使用委托

如果你显示一个Document Interaction Controller ,则必需要为delegate属性用指定一个委托。让委托告诉DocumentInteraction Controller如何显示。

documentController.delegate = self;

委托对象需要实现一系列委托方法,最常见的包括:

- documentInteractionControllerViewControllerForPreview:
- documentInteractionControllerViewForPreview:
- documentInteractionControllerRectForPreview:

这3个方法在用户点击“快速查看”菜单时依次调用。

- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller {return self;
}
- (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller {return self.view;
}- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller {return self.view.frame;}//点击预览窗口的“Done”(完成)按钮时调用
- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller {
}

功能一:分享文件

- (void)shareFile {NSString *filePath = [[NSBundle mainBundle] pathForResource:@"皮卡丘"ofType:@"jpeg"];//创建实例UIDocumentInteractionController *documentController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];//设置代理documentController.delegate = self;BOOL canOpen = [documentController presentOpenInMenuFromRect:CGRectZeroinView:self.viewanimated:YES];if (!canOpen) {NSLog(@"沒有程序可以打開要分享的文件");}
}

功能二:预览文件(注册应用程序支持的文件类型)

- (void)preview {if (!_path) {return;}NSURL *fileURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", [self getURL], [_path lastPathComponent]]];//创建实例UIDocumentInteractionController *documentController =[UIDocumentInteractionControllerinteractionControllerWithURL:fileURL];//设置代理documentController.delegate = self;[documentController presentPreviewAnimated:YES];
}

配置Info.plist文件

如果你的程序能够打开某种文件,你可以向系统进行注册。方便其他程序通过 iOS 的document interaction技术提供给用户一个选择,从而调用你的程序处理这些文件。

这需要在程序的Info.plist文件中添加CFBundleDocumentTypes键(查看CoreFoundation Keys)。

系统将该键中包含的内容进行登记,这样其他程序就可以通过document interaction controller访问到这些信息。

CFBundleDocumentTypes键是一个dictionary数组,每个dictionary表示了一个指定的文档类型。一个文档类型通常与某种文件类型是一一对应的。

但是,如果你的程序对多个文件类型采用同样的处理方式,你也可以把这些类型都分成一个组,统一视作一个文档类型。**例如,你的程序中使用到的本地文档类型,有一个是旧格式的,还有一个新格式(似乎是影射微软office文档),则你可以将二者分成一组,都放到同一个文档类型下。这样,旧格式和新格式的文件都将显示为同一个文档类型,并以同样的方式打开。**

CFBundleDocumentTypes数组中的每个 dictionary 可能包含以下键:

  • CFBundleTypeName

    指定文档类型名称。

  • CFBundleTypeIconFiles

    是一个数组,包含多个图片文件名,用于作为该文档的图标。

  • LSItemContentTypes

    是一个数组,包含多个UTI【Uniform Type Identifiers】类型的字符串。UTI类型是本文档类型(组)所包含的文件类型。

  • LSHandlerRank

    表示应用程序是“拥有”还是仅仅是“打开”这种类型而已。

下表列出了Info.plist中的一个CFBundleTypeName官方示例。

  1. 自定义文件格式的文档类型

    <dict>
    <key>CFBundleTypeName</key>
    <string>My File Format</string>
    <key>CFBundleTypeIconFiles</key><array><string>MySmallIcon.png</string><string>MyLargeIcon.png</string></array>
    <key>LSItemContentTypes</key><array><string>com.example.myformat</string></array>
    <key>LSHandlerRank</key>
    <string>Owner</string>
    </dict>
    
  2. 自己程序配置文件

    <key>CFBundleDocumentTypes</key>
    <array><dict><key>CFBundleTypeName</key><string>com.myapp.common-data</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>
    

打开支持的文件类型

你可以在应用程序委托的application:didFinishLaunchingWithOptions:方法中获得该文件的信息。如果你的程序要处理某些自定义的文件类型,你必须实现这个委托方法(而不是applicationDidFinishLaunching: 方法) 并用这个方法启动应用程序。

application:didFinishLaunchingWithOptions:方法的option参数包含了要打开的文件的相关信息。尤其需要在程序中关心下列键:

  • UIApplicationLaunchOptionsURLKey

    包含了该文件的NSURL。

  • UIApplicationLaunchOptionsSourceApplicationKey

    包含了发送请求的应用程序的 Bundle ID。

  • UIApplicationLaunchOptionsAnnotationKey

    包含了源程序向目标程序传递的与该文件相关的属性列表对象。

如果UIApplicationLaunchOptionsURLKey键存在,你的程序应当立即用该 URL 打开该文件并将内容呈现给用户。其他键可用于收集与打开的文件相关的参数和信息。

如果你的应用程序处于活跃状态,此时application:didFinishLaunchingWithOptions:方法是不会被调用的。需要实现application:openURL:options:方法

【以下是本人的写法】

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {_vc = [[ViewController alloc] init];UINavigationController *nav    = [[UINavigationController alloc] initWithRootViewController:_vc];self.window                    = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];self.window.backgroundColor    = [UIColor whiteColor];self.window.rootViewController = nav;[self.window makeKeyAndVisible];if (launchOptions) {NSString *str = [NSString stringWithFormat:@"\n发送请求的应用程序的 Bundle ID:%@\n\n文件的NSURL:%@\n\n文件相关的属性列表对象:%@",launchOptions[UIApplicationLaunchOptionsSourceApplicationKey],launchOptions[UIApplicationLaunchOptionsURLKey],launchOptions[UIApplicationLaunchOptionsSourceApplicationKey]];[[[UIAlertView alloc] initWithTitle:@""message:strdelegate:nilcancelButtonTitle:@"确定"otherButtonTitles:nil, nil] show];_vc.path = [launchOptions[UIApplicationLaunchOptionsURLKey] description];[_vc preview];}return YES;
}- (BOOL)application:(UIApplication *)application openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<NSString *,id> *)options {if (options) {NSString *str = [NSString stringWithFormat:@"\n发送请求的应用程序的 Bundle ID:%@\n\n文件的NSURL:%@", options[UIApplicationOpenURLOptionsSourceApplicationKey], url];[[[UIAlertView alloc] initWithTitle:@""message:strdelegate:nilcancelButtonTitle:@"确定"otherButtonTitles:nil, nil] show];_vc.path = [url description];[_vc preview];}return YES;
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/247954.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c#基础知识梳理(四)

上期回顾 - https://www.cnblogs.com/liu-jinxin/p/10826971.html 一、类 当你定义一个类时&#xff0c;你定义了一个数据类型的蓝图。这实际上并没有定义任何的数据&#xff0c;但它定义了类的名称意味着什么&#xff0c;也就是说&#xff0c;类的对象由什么组成及在这个对象…

UIButton设置圆角和边框及边框颜色

UIButton *testButton [UIButton buttonWithType:UIButtonTypeSystem];[testButton setFrame:CGRectMake(self.view.frame.size.width/2, self.view.frame.size.height/2, 100,100)];[testButton setTitle:"获取屏幕尺寸" forState:UIControlStateNormal];[testButt…

Objective-C 深复制和浅复制与NSCopying协议

1.简单复制只能实现浅拷贝&#xff1a;指针赋值&#xff0c;使两个指针指向相同的一块内存空间&#xff0c;操作不安全。 2. Foundation类已经遵守了<NSCopying>和 <NSMutableCopying>协议,即实现了copy和mutableCopy方法,因此Foundation对象可以使用这些方法创建对…

NSTimer 进阶使用总结与注意事项

NSTimer 是 iOS 上的一种计时器&#xff0c;通过 NSTimer 对象&#xff0c;可以指定时间间隔&#xff0c;向一个对象发送消息。NSTimer 是比较常用的工具&#xff0c;比如用来定时更新界面&#xff0c;定时发送请求等等。但是在使用过程中&#xff0c;有很多需要注意的地方&…

一步一步教你实现iOS音频频谱动画(一)

如果你想先看看最终效果再决定看不看文章 -> bilibili示例代码下载 第二篇&#xff1a;一步一步教你实现iOS音频频谱动画&#xff08;二&#xff09; 基于篇幅考虑&#xff0c;本次教程分为两篇文章&#xff0c;本篇文章主要讲述音频播放和频谱数据的获取&#xff0c;下篇将…

微信小程序的基础 (一)

微信小程序介绍- 链接 微信小程序&#xff0c;简称小程序&#xff0c;是一种不需要下载安装即可使用的应用&#xff0c;它实现了应用“触手可及”的梦想&#xff0c;用户扫一扫或搜一下即可打开应用 1. 为什么是微信小程序? 微信有海量用户&#xff0c;而且粘性很高&#x…

IDEA提交项目到SVN

一.提交步骤 VCS--Enable...-->点击项目右键-->subversion-->share directory-->commit 二.IDEA SVN 忽略文件的设置 1》share .使用idea在将项目提交到svn的过程中遇到这样的问题 将项目share之后再设置ignore files &#xff0c;在commit的时候&#xff0c;不会将…

项目ITP(五) spring4.0 整合 Quartz 实现任务调度

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主同意不得转载。https://blog.csdn.net/u010378410/article/details/26016025 2014-05-16 22:51 by Jeff Li 前言 系列文章&#xff1a;[传送门] 项目需求&#xff1a; 二维码推送到一体机上&#xff0c;给学生签到扫…

喜欢用Block的值得注意-Block的Retain Cycle的解决方法

本文不讲block如何声明及使用&#xff0c;只讲block在使用过程中暂时遇到及带来的隐性危险。 主要基于两点进行演示&#xff1a; 1.block 的循环引用(retain cycle) 2.去除block产生的告警时&#xff0c;需注意问题。 有一次&#xff0c;朋友问我当一个对象中的block块中的访问…

【PyQt5】QT designer + eclipse 集成开发

【写在前面的话】 考虑将pyqt5的界面开发qt designer 集成在eclipse中&#xff0c;并且&#xff0c;不利用cmd命令行进行转换。 【工具】 1、pyqt5 2、qt designer 3、eclipse pydy 【步骤】 1、首先配置Qt designer。 菜单 run-->external Tools-->External tools confi…

iOS UIlabel文字排版(改变字间距行间距)分类

在iOS开发中经常会用到UIlabel来展示一些文字性的内容&#xff0c;但是默认的文字排版会觉得有些挤&#xff0c;为了更美观也更易于阅读我们可以通过某些方法将UIlabel的行间距和字间距按照需要调节。 比如一个Label的默认间距效果是这样&#xff1a; 然后用一个封装起来的Cat…

iOS 富文本风格NSMutableParagraphStyle、定制UITextView插入图片和定制复制

问题一 开发过程中&#xff0c;经常会遇到动态计算行高的问题&#xff0c; - (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(nullableNSDictionary<NSString *, id> *)attributes context:(nullable NSStringDrawingC…

线程模块

信号量 from threading import Semaphore,Thread import timedef func(a,b):time.sleep(1)sem.acquire()print(ab)sem.release()sem Semaphore(4) for i in range(10):t Thread(targetfunc,args(i,i5))t.start() 信号量事件 # 事件被创建的时候&#xff0c;默认为False状态 #…

React中级学习(第一天)

Props深入 children 作用 : 获取组件标签的 子节点获取方式 : this.props.children <App>此处的内容&#xff0c;就是组件的 children&#xff0c;将来通过组件的 props.children 就可以获取到这些子节点了 </App>props 校验 作用&#xff1a;规定组件props的类…

Elasticsearch集成ik分词器

1、插件地址https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.0.0/elasticsearch-analysis-ik-7.0.0.zip 2、找到对应版本的插件通过 http://192.168.1.8:9200查看ES的版本&#xff0c;找到对应的IK分词插件 下载与之对应的版本https://github.com/me…

iOS NSTextAttachment - 图文混排

苹果在iOS7中推出了一个新的类NSTextAttachment&#xff0c;它是做图文混排的利器&#xff0c;本文就是用这个类&#xff0c;只用50行代码实现文字与表情混排&#xff0c;当然也可以实现段落中的图文混排。 首先说一下文字和表情的混排&#xff1a; 先来做点儿准备工作&#…

iOS 自定义Cell按钮的点击代理事件

在实际开发工作中&#xff0c;我们经常会在自定义的Cell中布局一些按钮&#xff0c;并且很多时候我们会在点击这个按钮的时候使我们的UItableviewController跳转到下一界面&#xff0c;有的可能还要传值。那么如何使我们的控制器能够获知我们按下了cell的按钮呢&#xff1f;毫无…

js - (初中级)常见笔试面试题

1.用 js 实现一个深拷贝 2.用 js 写一个数组去重 3. 用 js 对字符串进行反转 4. 用 js 请求范围内的质数个数 5.用 js 求数组中出现最多的数及其出现次数

iOS 支付宝SDK接入详解

一&#xff0c;在支付宝开放平台下载支付宝SDK&#xff08;https://openhome.alipay.com/platform/document.htm#down&#xff09; https://doc.open.alipay.com/doc2/detail.htm?spma219a.7629140.0.0.HpDuWo&treeId54&articleId104509&docType1 二&#xff0c;添…

面试基本知识点

文章目录面-什么是SEO面 - cookie / localstorage / sessionstorage的区别面 - promise面试题面 - 柯里化函数面 - 函数节流面 - 函数防抖HTML / CSS 知识点1、讲讲盒模型&#xff08;蚂蚁金服 2019.03 招行信用卡 2019.04 美团 作业帮&#xff09;2、根据盒模型解释边距重叠&a…