iOS的应用程序实现之间的内容分享

前言

我们在iOS的平台上想要实现不同应用之间的内容分享一般有几种常用方式:

  1. 一种第的英文通过AirDrop实现不同设备的应用之间文档和数据的分享;
  2. 第二种是给每个应用程序定义一个URL方案,通过访问指定了URL Scheme的一个URL,实现直接访问一个APP;
  3. 第三种是通过UIDocumentInteractionController或者是UIActivityViewController这两个个iOS SDK中封装好的类在App之间发送数据,分享数据和操作数据;
  4. 第四种是通过App Extension,在iOS 8的SDK中提供的扩展新特性实现跨应用的数据操作和分享;
  5. 还有一种集成第三方SDK实现的有限个应用的数据分享,比如社交平台(QQ,微信,新浪微博等)给我们提供的官方SDK,或者是集成了多个社交平台的ShareSDK组件和友盟分享组件等。

关于集成第三方SDK的使用,各大平台官网上都有详细的文档说明,因此我们这系列文章主要是来谈谈苹果原生提供的基于iOS SDK的分享技术,同时推荐俩篇苹果开发者中心的文档:应用间通信文档交互编程主题为iOS。我们的第一篇文章就谈一下如何通过UTI让我们的应用程序支持分享。

原理

我在“详解苹果提供的UTI(统一类型标识符)”这篇文章中,详细地讲讲了一下UTI(Uniform Type Identifier),一套苹果给我们提供用于在可可和可可触摸应用程序中识别实体内容类型的规范,而关于实现内容关联的技术也正是基于这套规范。在iOS和Mac OS开发中,苹果给我们提供了注册文档类型的接口,而这种注册的文档类型是全局的,系统中所有的应用程序和服务都可以侦测到。因此我们通过这个底层侦测,使用可以可选其他的第三方App来预览我们的App中不请立即获取iTunes的文档,我们而且还可以通过这个接口在我们的App中打开并处理第三方App的文档。

如果我们的应用程序可以处理某些类型的实体内容,我们那么就可以在我们项目中的Info.plist文件中进行注册。关于使用哪种类型和UTI,就要参考我在“详解苹果提供的UTI(统一类型标识符)“这篇文章中的讲解。当一个第三方应用程序通过苹果的底层侦测技术检查有哪些应用程序可以处理它所指定的内容类型时,如果我们的应用程序已经注册了这种类型,那么我们的应用程序图标就会显示在其中,并且作为我们自己的应用程序的一个入口。

主要技术

主要应用到这种底层侦测的技术有iOS SDK中给我们提供的UIDocumentInteractionControllerUIActivityViewControllerQuick Look 框架。此外,在iOS 8中,苹果还给开发者提供了App Extension,一种更高大上的方式在App之间的实现分享内容。关于UIDocumentInteractionControllerUIActivityViewControllerQuick Look 框架以及App Extension的细节,我计划在后面的文章中详细讲解这篇。文章,主要我们的英文来谈谈如何注册我们App可用的文档类型以及简单使用我们的App来处理第三方App分享的内容

注册可用类型

需要我们在info.plist文件中,添加一个新的属性CFBundleDocumentTypes(实际上输入的是"Document types"),这是一个数组类型的属性,意思就是我们可以同时注册多个类型。而针对数组中的每一个元素,都有许多属性可以指定,详细的属性列表我们可以从官方文档上找到:Core Foundation Keys ---- CFBundleDocumentTypes。这里列举我们在做iOS开发时常用的属性:

  • CFBundleTypeName("Icon File Name"
    字符串类型,指定某种类型的别名,也就是用来指代我们规定的类型的别称,一般为了保持唯一性,我们使用UTI来标识。
  • CFBundleTypeIconFiles 
    数组类型,包含指定的PNG图标的文件名,指定代表某种类型的图标,而图标有具体的尺寸标识:
设备 尺寸
iPad的 64 x 64像素,320 x 320像素
iPhone和iPod touch 22 x 29像素,44 x 58像素(高分辨率)
  • LSItemContentTypes("Document Content Type UTIs"
    数组类型,包含UTI字符串,指定我们的应用程序所有可以识别的类型集合
  • LSHandlerRank( "Handler rank"
    字符串类型,包含OwnerDefaultAlternateNone四个可选值,指定对于某种类型的优先权级别,而Launcher Service会根据这个优先级别来排列显示的应用程序的顺序。优先级别从高到低依次是OwnerAlternateDefaultNone表示不接受这种类型。

了解这些基本属性,我们就需要在注册App可用类型时,指定这些属性,根据每个项目的需求不同,属性值也不同。具体注册请参照我的GitHub上的项目:SeraZheng --- ZSUTITest。下图示例作为一个参照:

在信息中添加文档类型

而当我们添加完所有属性后,开始运行我们的程序,然后再回到我们的信息界面,看到就会Document types这个列表已经发生了变化,这就证明我们成功的注册好了应用程序可用的类型。

注册成功,运行程序显示的结果

打开第三方应用

我们在上面的步骤中注册好了我们的应用程序可以识别的类型,现在我们可以打开一个使用UIDocumentInteractionController或者是Quick Look框架来展示内容的第三方App,这里以iPhone上的QQ程序为例。

我们在上面的注册步骤中,的注册LSItemContentTypes仅所有游戏了public.image这个UTI。所以我们先从QQ程序应用的我的文件中,打开不同类型的文件进行对比,可以大家看下图产品我的文件列表中所有游戏俩种类型的文件,一种的英文.jpg扩展名的图片文件,的英文一种.pdf扩展名的文档文件。

我的文件列表

当我打开一个图片文件进行预览时,点击其他应用打开,就可以在应用程序列表中看到我们的应用程序图标。简单介绍一下这个页面,第一行是苹果在iOS的7给之后我们提供的使用AirDropiPhoneiPadiPod Touch设备之通过间iCloud共享内容的一种方式。第二行是通过文档类型关联技术识别的应用程序的列表。行第三的英文通过文档关联技术识别的Action的列表,Action表示对文档可进行的操作,如复制,打印等。

打开图片,显示ZSUTITestDemo App图标

而如果我打开PDF文件的话,就看不到我们的应用程序图标。

打开PDF文件,看不到ZSUTITestDemo App图标

程序回调

当我们通过上面步骤,成功地显示了ZSUTITestDemo的图标之后,点击图标,我们就可以跳转到ZSUTITestDemo应用中,而苹果在iOS SDK中给我们提供的接收回调的方法在iOS 9之后做出了改变,因此我们需要针对不同的设备版本做出改变:

#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation
{
    UINavigationController *navigation = (UINavigationController *)application.keyWindow.rootViewController;
    ViewController *displayController = (ViewController *)navigation.topViewController;

    [displayController.imageView setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:url]]];
    [displayController.label setText:sourceApplication];

    return YES;
}

#else
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(nonnull NSDictionary<NSString *,id> *)options
{
    UINavigationController *navigation = (UINavigationController *)application.keyWindow.rootViewController;
    ViewController *displayController = (ViewController *)navigation.topViewController;

    [displayController.imageView setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:url]]];
    [displayController.label setText:[options objectForKey:UIApplicationOpenURLOptionsSourceApplicationKey]];

    return YES;
}
#endif

演示示例可以从GitHub项目上参照代码:SeraZheng --- ZSUTITest。当点击ZSUTITestDemo程序图标回到调用代码中,我们可以在这里做各种我们想做的事,如上传图片,预览图片,操作图片等等。我只对图片做了简单的预览显示,然后显示文件的源程序的Bundle Identifier,示例如下图:

时间: 2024-12-28 20:50:10

iOS的应用程序实现之间的内容分享的相关文章

浅谈高大上的微信小程序中渲染html内容—技术分享

大部分Web应用的富文本内容都是以HTML字符串的形式存储的,通过HTML文档去展示HTML内容自然没有问题.但是,在微信小程序(下文简称为「小程序」)中,应当如何渲染这部分内容呢? 解决方案 wxParse 小程序刚上线那会儿,是无法直接渲染HTML内容的,于是就诞生了一个叫做「 wxParse 」的库.它的原理就是把HTML代码解析成树结构的数据,再通过小程序的模板把该数据渲染出来. rich-text 前端精品教程:百度网盘下载 后来,小程序增加了「rich-text」组件用于展示富文本内

关于 Des加密(Android与ios 与后台java服务器之间的加密解密)

关于 Des加密(Android与ios  与后台java服务器之间的加密解密) http://blog.sina.com.cn/s/blog_7c8dc2d50101id91.html (2013-04-17 11:47:23)   分类: iPhone开发 最近做了一个移动项目,是有服务器和客户端类型的项目,客户端是要登录才行的,登录的密码要用DES加密,服务器是用Java开发的,客户端要同时支持多平台(Android.iOS),在处理iOS的DES加密的时候遇到了一些问题,起初怎么调都调不

iOS开发拓展篇—应用之间的跳转和数据传递

iOS开发拓展篇—应用之间的跳转和数据传 说明:本文介绍app如何打开另一个app,并且传递数据. 一.简单说明 新建两个应用,分别为应用A和应用B. 实现要求:在appA的页面中点击对应的按钮,能够打开appB这个应用. 1.新建两个应用,分别为A和B.     2.设置应用B的url. 3.在应用A中编写打开app的代码 点击之后,会跳转到新的控制器. 注意:打开应用B的过程中,B有两种状态. 第一种状态:B并没有启动,那么会启动B.并调用下面的方法. 第二种状态:此时B已经启动了,但是在后

iOS之应用程序国际化

iOS之应用程序国际化 一.程序国际化 准备工作: 1.首先我们要先创建一个工程,我们给他命名Internationalization-Demo,然后添加语言. 从代码中分离文本: 目前,应用展示的所有文本都是以硬编码字符串存在于Main.storyboard 和 ViewController里.为了本地化这些字符串,你需要把它们放在一个单独的文件中.他将会在包中简单地引用这些字符串,而不是在你的方法中进行硬编码.Xcode使用带有 .strings 扩展名的文件来存储和检索app中使用的所有字

iOS获取.ipa程序包

iOS获取.ipa程序包 原文在此 首先肯定不是获取自己的ipa包. 为什么要获取ipa包呢?比如,在仿写一些程序时,避免不了获取它的图片素材等等,那么最快也是最有效的方式就是获取原程序的ipa包.更或者,你想要逆向分析某一款APP时,那么只有获取了ipa后才能进行class-dump,ida等等后续工作. 一.通过越狱设备 如果有越狱手机,那么就变得很简单,只需要从AppStore下载到越狱手机,然后用iTools/PP助手等工具将ipa包备份到电脑即可,下图是使用PP助手: 如果只是为了获取

iOS的应用程序app的生命周期

iOS的应用程序的生命周期,还有程序是运行在前台还是后台,应用程序各个状态的变换,这些对于开发者来说都是很重要的. iOS系统的资源是有限的,应用程序在前台和在后台的状态是不一样的.在后台时,程序会受到系统的很多限制,这样可以提高电池的使用和用户体验. //开发app,我们要遵循apple公司的一些指导原则,原则如下: 1.应用程序的状态 状态如下: Not running  未运行  程序没启动 Inactive          未激活        程序在前台运行,不过没有接收到事件.在没

如何:在 DHTML 代码和客户端应用程序代码之间实现双向通信

https://msdn.microsoft.com/zh-cn/library/a0746166 可以使用 WebBrowser 控件向 Windows 窗体客户端应用程序添加现有的动态 HTML (DHTML) Web 应用程序代码. 在投入大量的开发时间创建基于 DHTML 的控件,并希望利用丰富的 Windows 窗体用户界面功能而无需重写现有的代码时,该控件十分有用. 使用 WebBrowser 控件,可以通过 ObjectForScripting 和 Document 属性在客户端应

iOS开发拓展篇—应用之间的跳转和数据传

iOS开发拓展篇—应用之间的跳转和数据传 说明:本文介绍app如何打开另一个app,并且传递数据. 一.简单说明 新建两个应用,分别为应用A和应用B. 实现要求:在appA的页面中点击对应的按钮,能够打开appB这个应用. 1.新建两个应用,分别为A和B.     2.设置应用B的url. 3.在应用A中编写打开app的代码 点击之后,会跳转到新的控制器. 注意:打开应用B的过程中,B有两种状态. 第一种状态:B并没有启动,那么会启动B.并调用下面的方法. 第二种状态:此时B已经启动了,但是在后

iOS中TableViewController的cell重用出错(内容错乱)

iOS中TableViewController的cell重用出错(内容错乱) - 简书 时间 2016 用我的双手,成就你的梦想 ---栋哥 今天我的心爱的程序又出现bug,对于我这个小菜来说,不得不说是非常苦恼的,主要是cell加载的时候因为重用池的问题而出现各种的bug,虽然程序没有崩掉,但是大大影响到我的心情,下面是最主要的一个问题 ,就是cell的重用问题, cell因为从重用池中调取,没有及时删除上面的内容而导致内容的各种出现, 这里有几个解决方案. UITableView继承自UIS