iOS App Extension
App Extension部分是iOS8之后苹果对App提供的一个功能性扩展,它以Target的形式存在于工程中,个人觉得这部分是苹果对其封闭系统的一个弥补。
一些常见的App Extension(file-new-target):

Call Directory用来处理来电时的事项,比如黑名单机制、来电标记提醒等等;

Photo Editing用来在相册选中相片编辑时的扩展,可以直接对相片进行一个编辑处理,而不必打开对应的工具类App;

Share用来对文件进行一个直接的分享功能,他不用唤起主App就能完成文件的分享,例如微信的相片分享;

Today 用来给用户展示App最新的状态或者兴趣点,他和通知不同的是他不是即时推送但能展示更多自定义的内容,例如内置的天气扩展;

Broadcast Setup UI和Broadcast Upload是直播推流的两个扩展,UI用作直播前和直播的一个桥接,在这个控制器中我们可以做一些自定义的事件,例如账号密码登陆等,Upload则是对直播过程中的状态控制和数据流的处理。
约定几个词:
容器App:主程序App,Extension随其一起打包的App
宿主App:Extension当前依托某个App而存在的App,这个App可以是其主程序App也可以是其他App。
Extension一般以以下几种方式工作:
1.和系统交互
和系统的交互这部分Extension主要做展示和响应。例如Today的内容展示和Call Directory的来电响应,在这个过程中,Extension基本上只和系统做数据的交互处理和展示,容器App只会做一些被动从Extension打开这种交互。
2.和宿主App的交互

这部分和系统交互很像,其实完全可以把系统看做宿主App,毕竟Extension是无法脱离宿主存在的。这部分经常用到的Extension主要有Share,Custom Keyboard等。
3.容器App、Extension和宿主App三方的交互

此时容器App != 宿主App,从图上我们可以看出Extension起到了媒介的作用,链接了容器App和宿主App,而数据通过Group Share的方式在Extension和容器App间进行共享。这种交互方式我觉得其实是不多的,首先,Extension独立于容器App而存在,宿主App在使用Extension时大部分的数据处理和交互其实由Extension就已经完成了,无需容器App的参与(如果需要容器App的参与其实open容器App在其内部操作就可以了Extension反而显得鸡肋);然后,Extension在其生命周期内和宿主App进行交互的时候,容器App很可能并没有启动, 我们需要唤醒容器App并且进行进程间的通信,这在目前是很繁琐的一件事情;最后,如果三方非要做交互,更多的我觉得是容器App对Extension从宿主App中获得数据的处理和响应,但这点同样和2一样,为什么不直接打开容器App直接和宿主App进行交互呢?所以我觉得这种交互方式并不常用。
App Extension以一个独立的Target形式存在于工程中,打包之后又是以一个独立的二进制文件和主程序分离,所以对于Extension的处理和主程序是不同的。
1.无法使用主程序的头文件,无法访问主程序的shareApplication。你可能注意到我在Extension中是可以导入主程序的一些头文件的,但是切换Target到Extension后缺无法编译成功,我们可以打开工程查看Build Phases选项卡中的资源文件,Extension下的资源文件仅仅是在Extension文件夹下的那部分,主程序的资源文件其实并没有被copy或者link进来,这就意味着Extension无法使用主程序的资源文件。如何解决呢?比较好的方式是封装一下公用的类为framework,在link binary中加入这个framework。
2.Extension的调试需要宿主App。Extension是不可以单独存在的,从开发到打包上架再到使用,Extension都需要一个宿主App,我们在开发调试时也会为其选择一个宿主App(开发调试时一般是容器App)。我们需要切换到对应的Extension Target才能开发调试:Xcode左上角选择对应的Target,选择宿主App,run。
3.Extension与容器App的资源共享问题。独立存在的Extension同样拥有独立的沙盒,即使是容器App也是不能直接访问的,我们可以使用App Group的方式和容器App共享我们的数据,关于App Group会另开篇幅。
4.一些Extension可能会被任意一个App调用。如果你的App只是想做一个App内的扩展工具,使用Extension显然不是一个好的选择,任何一个App都有可能唤起你的Extension,如果你去做了校验不去对其他App进行数据处理和响应,反而显得你的这个Extension非常的鸡肋。所以我们在对工具类的Extension选择上要慎重。
因为每种Extension都有其独特的构造方式,所以这里不再说每种如何去使用,search一下网上资源非常的多,之前有一个关于Broadcast Setup UI和Broadcast Upload的Extension可以作为参考。