App Extension应用扩展

App Extension应用扩展

对于App Extension, 相信大家并不陌生,在iOS8系统中,苹果为了使app间数据甚至功能进行共享,就有了 扩展 这一功能,
应用程序扩展不是一个应用,相反,它是主体应用程序(containing app)中一个单独的包,并能生成单独的二进制文件。与主体应用程序不同,应用扩展实现的是一个特定的、狭义范围内的任务,并且要严格遵循扩展点的协议。下面主要在四个方面进行讲解。

  • 1. 名词解释 App Extension
  • 2.应用扩展的类型
  • 3.应用程序扩展的生命周期
  • 4.应用扩展是如何进行通信的

1.名词解释 App Extension

基于iOS系统的安全性考虑,其应用的数据存储是通过沙盒模式进行的,要实现应用之间的数据共享十分困难,功能共享就更加棘手。在iOS8系统中,apple为我们提供了一个革命性的功能:扩展。我们可以通过扩展来使app间数据甚至功能进行共享。

沙盒 - 应用程序只能在该程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文本文件等。总体来说沙盒就是一种独立、安全、封闭的空间。

应用扩展程序可以让我们自定义功能和内容扩展到应用程序之外,并在用户与其他应用程序或系统交互时提供给用户使用。

2.应用扩展的类型

在iOS8种,只有6种扩展, 包括Today Extension, Share Extension,Action Extension, Photo Editing Extension, Custom Keyboard Extension, Storage Provider Extension, 后来又先序有很多扩展点,具体看图
App Extension应用扩展
App Extension应用扩展

介绍一下常见的扩展

1.Today Extension 以前在通知 today 那栏 现在在spotLight那栏,对于有扩展功能的APP,安装APP的时候,扩展同时也安装了,可在spotlight下 点击Edit 进行添加扩展。如图天气,备忘录 都是系统的扩展,主要是用来进行展示的,同时可以与app进行交互。
App Extension应用扩展

2.Share Extension 分享扩展可以使用户在不同的app之间分享内容。这个功能在iOS5的时候就已经出来了,但是仅限于相册分享图片到tweeter,iOS6中可以分享到Facebook,但是现在,我们可以写分享扩展来分享到我们自己的服务器。

比如我有一张相册中的图片想要通过微信发送给我的朋友,如果没有分享扩展,我只能打开微信与朋友聊天的界面 -> 选择发送图片 -> 到相册中选择图片 -> 然后发送。但是有了分享扩展,我可以直接在相册中点击分享按钮,点击微信,选择好友后,直接分享给好友,而不用打开微信来发送了。
App Extension应用扩展App Extension应用扩展

3.Action extensions(行为扩展): 行为扩展这个名字有点难理解,它可以让用户查看和改变一个app中的某些内容,而不用离开这个app。

比如我在知乎看帖子,碰到一个不会的单词,咋办?如果没有应用扩展,我只能切换到有道词典,输入这个单词来查看,然后再切回知乎,但是现在有了有道词典的行为扩展,我只要复制这个单词,点击共享,在下面 选择有道词典的扩展,就可以不用打开有道词典这个app了,而直接能够显示出翻译结果。

4.Photo Editing extensions (图片编辑扩展):图片编辑扩展可以使用户直接在iphone的手机相册中利用第三方图片编辑软件提供的扩展来编辑图片。

比如我现在有一张自拍照,想要编辑一下。如果没有图片编辑扩展的话,我只能打开美图秀秀之类的图片编辑软件,导入图片,编辑保存。有了图片编辑扩展之后,我只需要在系统相册中找到这张图片,点击分享按钮调出菜单,选择第三方的图片编辑扩展,就可以直接进入编辑界面,编辑完直接保存,而不用再打开这个图片编辑软件导入图片来进行编辑了。但是这个扩展仅限于在自带的相册中进行编辑,而不是所有app中图片都可以。

5.Document Provider extensions (文件提供者扩展):文件提供者扩展会显示一个文件选择视图给用户,这些选择项可以让用户导入,导出,或者用其他app来打开这个文件。

6.Custom Keyboard extensions(自定义键盘扩展):自定义键盘扩展可以让开发者创建系统键盘之外的自定义键盘,比如搜狗输入法。

3.应用程序扩展的生命周期

一些名词解释

extension并不是一个独立的app,它有一个包含在app bundle中的独立bundle,extension的bundle后缀名是 .appex

containing app

尽管苹果开放了extension,但是在iOS中extension并不能单独存在,要想提交到AppStore,必须将extension包含在一个app中提交,并且app的实现部分不能为空,这个包含extension的app就叫containing app。

extension会随着containing app的安装而安装,同时随着containing app的卸载而卸载。

host app
能够调起extension的app被称为host app,比如widget的host app就是Today。

举例:

在Safari上点击微博的分享按钮,就会弹出微博的输入框,然后按分享。那么Host app就是Safari,而App extension则是那个弹出来的微博输入框,Containing app则是微博。

App extension虽然是属于Containing app,但是它是独立出来就像是另一个app一样.所以打开微博,则需要使用Url scheme,共用数据则需创建共享空间。

生命周期

因为一个应用程序扩展不是一个应用,所以它的生命周期和运行环境也不同于应用。一般情况来说,应用程序扩展的生命周期始于用户从某个应用中启动它。允许用户选择某一种扩展来帮助他们执行某项任务的应用,我们称之为扩展的“载体应用”(host app)。“载体应用”(host app)定义了**扩展的上下文环境,并在其发送请求以响应用户操作时开始扩展的生命周期。当应用扩展完成载体应用发送的请求任务后,该扩展的生命周期也随之结束。

比如说,假定这样一个场景,用户在扩展载体应用(host app)中选中一段文字,点击分享按钮,并从分享列表中选择某一个分享扩展,将选中的内容分享至社交网站。此时,载体应用就会向扩展发送一个包含用户所选文本的请求,启动该扩展,从而去响应用户的请求,即分享所选文本的内容。应用扩展基本的生命周期归纳在下图中。

App Extension应用扩展

在上图中的第2步中,系统实例化载体应用请求中确定的扩展,并在两者之间建立通信通道。然后扩展在载体应用的上下文场景中显示相关界面,并使用其在载体应用请求中接收到的项目来执行任务(在上述的例子中,扩展接收到的项目是用户选中的文本)

在上图的第3步中,用户在扩展中执行或取消某个任务,或者直接可以忽略该扩展。在对用户的操作做出响应的过程中,扩展会根据载体应用的请求立即开始执行任务,但如果有特殊需要时,扩展也会在系统后台执行任务,这种情况下,载体不会显示扩展相关界面,并且用户返回到其先前在载体应用中的上下文环境。当应用扩展执行完任务后,不管是立刻返回还是延迟返回,但最后其执行结果都会返回给载体应用。

总结:

extension和普通app的最大区别之一是生命周期。
开始 在用户通过host app点击extension时,系统就会实例化extension应用,这是生命周期的开始。
执行任务 在extension启动以后,开始执行它的使命。
终止 在用户取消任务,或者任务执行结束,或者开启了一个长时后台任务时,系统会将其杀掉。

4.应用扩展是如何进行通信的

应用扩展在运行的时候,它只会直接和载体应用(host app)进行通信,而扩展和containing app之间不会直接通信。在扩展运行的过程中,主体应用(containing app)甚至都不运行。另外,载体应用(host app)和主体应用(containing app)之间也不会进行通信。

图描述了运行中的应用扩展、载体应用(host app)以及主体应用(containing app)这三者之间的关系。

运行中的扩展仅和载体应用进行通信。

App Extension应用扩展

注:extension和host app
extension和host app之间可以通过extensionContext属性直接通信,该属性是新增加的UIViewController类别:
App Extension应用扩展

当一个扩展需要和containing app进行通信时,只能在载体应用确定的上下文环境中进行间接通信。比如,一个应用扩展有可能会运行调用它的应用程序。在这个例子中,扩展使用了不能与 containing app 传递消息的API。此外,应用扩展与其 containing app 可以在一个定义为私有的共享容器中访问数据。下图描述了扩展和 containing app 之间的间接通信类型。

运行中的扩展可以与其containing app进行间接通信。

App Extension应用扩展

注:extension和containing app

不能直接通信,首先,尽管extension的bundle是放在containing app的bundle中,但是他们是两个完全独立的进程,之间不能直接通信。不过extension可以通过openURL的方式启动containing app(当然也能启动其它app),不过必须通过extensionContext借助host app来实现:

可以共享Shared resources,extension和containing app可以共同读写一个被称为Shared resources的存储区域,这是通过App Groups实现的,

App Extension应用扩展

宿主应用和应用扩展之间的空间关系
App Extension应用扩展

参考资源:
—— [ WWDC2014之App Extensions学习笔记 ]

—— [ App Extension Programming Guide ]

推荐文章

—— [ Today Extension 水哥]

—— [ Today Extension 小敏]

—— [ Today Extension segmentfault]

—— [ Today Extension cocoachina]

—— [ Share Extension]