转自:http://www.cocoachina.com/ios/20160619/16760.html

本文授权转载,作者:Cyandev(简书

从 iOS 8 开始,苹果引入了全新的 App Extension,涉及到方方面面,例如今日面板、键盘、内容拦截器、分享动作等。但是官方对于 App Extension 的开发指南少之又少,入门起来会有很多坑。所以我准备写一系列文章来帮助大家更好入门 App Extension 的开发,也能少走弯路。

何为 App Extension?

顾名思义,它是一种扩展,很类似于一些大型软件(好吧,现在可能是个应用都可以有)的插件机制。App Extension 事实上并不是你应用的插件,而是系统的插件,其生命周期是由系统来管理的,所以如果你想做什么坏事还是行不通的...但是 App Extension 分发的载体是应用,也就是说如果你只是单纯想做一个今日面板插件,也需要有个主程序,你的主程序可以什么都不做,也可以提供一些基本的设置和数据。

App Extension 和主程序的关系?

可以说没有什么关系,基本上就是两个独立的程序,你的主程序既不可以访问 App Extension 的代码,也不可以访问其存储空间,这完完全全就是两个进程、两个程序。这时你可能会问,我擦,都不能交互那有什么卵用??别急,后面我会讲到如何做一些交互。

App Extension 可以干什么?不可以干什么?

基本上什么都能干,有人不是在今日面板里把 Chrome 的恐龙小彩蛋硬塞进去了吗?还有拿输入法当浏览器作分屏多任务的...只有你想不到,没有你做不到......诶等等,有些还是做不到的。比如,内存有限制,App Extension 的可用内存远不如常规应用,以至于如果你真想做游戏,还是掂量掂量你的资源占用问题能不能解决吧。而且还不能访问 UIApplication,因为它的容器应用是系统,你拿系统的 UIApplication 想干嘛...(当然,你可以用递归查找 UIResponder 的方法拿到 UIApplication,但是我没试过)再次,你不能执行长时间的操作,你的 App Extension 可能随时被系统 Kill 掉,who knows?

还有更多不可用的 API 可以看这个苹果官方文档:Understand How an App Extension Works

开始创建一个 App Extension

首先看一下我们要做的东西,是一个简单 Todo 应用,主程序长这个样:

今日面板插件长这个样:

界面都很简单啦~

主程序实现其实很简单,就是 Table View 的使用以及数据持久化,这里就不着重讲了。但注意,我们要留出一个接口给今日面板,假设这里我们要在今日面板里显示前 4 条待办事项,我们必须要单独将这 4 条存在一个主程序和扩展都能访问的地方。后面我会说怎么做。

Tips:

苹果的 HIG 明确指出,不要在今日面板里使用可以滚动的 Scroll View,而是要完全展开,因此对于多条数据,我们要不就分页,要不就只显示前几项。

下面,我们就为工程创建一个 Today Extension:

一路下一步,输入一个子项目名,点 『Finish』就完成 Today Extension 的添加了。

这个子项目的初始目录结构如下:

P.S. 那个 entitiements 文件是后来创建的,一开始不会有

然后我们在 Storyboard 里把大致界面拖出来,如果画布大小不合适可以在这调整一下,但是也就是调整了预览效果,真实的大小不能在 IB 里修改。

那我们怎么修改视图在今日面板里的大小呢?答案是修改 View Controller 的 preferredContentSize 属性,不理会 width,调整 height 到合适的大小即可,因为宽度总是和屏幕宽度相同的。

在这个例子中,我使用 44 * 项目数量 - 1 来作为视图高度,因为一个标准 Table View Cell 的高度是 44,然后减掉最后一个条目分割线的高度就是我们理想的合适高度。

主程序向 App Extension 共享数据

我们在主程序里创建了待办事项,怎么才能让 App Extension 获取到呢?由于两者代码和数据都不互通,所以我们 可以理所当然的想到用 App Group 来解决。首先在主程序中创建一个 App Group:

然后在 App Extension 里添加这个 App Group 即可。

这样,我们就可以用 NSUserDefaults 通过这个 App Group 交流数据了。

还记得我说过要拿出所有数据的前四条放到今日面板中展示吗?下面我们就来实现这个功能:

当主应用的数据变化后就调用这个方法来更新快照数据。

下面我们主要来看 Today Extension 怎么实现,首先看看这两个方法:

其中第一个方法是系统告诉 Extension 需要更新了,当你更新完毕之后通过 block 回调告诉系统你完成了还有做了什么,通常我们就告诉系统我们更新数据了即可(就是给 block 传 NCUpdateResultNewData 枚举项作为参数)。

其中第二个方法是返回一个内补大小,如果不实现,默认情况视图左侧会有一定的缩进。当然,苹果还是希望你不要修改默认的内补~

然后我们实现数据的读取:

P.S. 第三行写错了,不要管它

其实也很简单,就是从 App Group 的配置里拿出前 4 项的快照,然后更新一下 Table View 即可。这个方法在 viewDidLoad 或者 widgetPerformUpdateWithCompletionHandler: 中调用都可以。

到这我们看看效果,选中 Today Extension 的那个 Scheme 点击调试按钮,弹出下面的对话框:

选择我们的主程序,点击 『Run』。

App Extension 调起主程序并执行动作

当我们的 Todo List 是空的情况下,我们希望在今日面板里展示一个按钮,点击后可以快速进入创建 Todo 的界面,就像这样:

由于我们访问不了主程序的代码,所以只剩下一条路可以选,那就是 URL Scheme。

首先,我们给主程序注册一个 URL Scheme:

然后响应按钮点击:

由于 App Extension 访问不了 UIApplication,因此不能用它的 openURL:,但是我们可以用 extensionContext 来打开 URL,用法和效果是一样的。

回到主程序,我们处理 URL 的打开:

这里我用 Notification 的方式告知指定 View Controller 来执行相应动作,当然你也可以用你自己喜欢的方式,这里最复杂也就是处理路由,现在也有很多方法实现,我这里就不深究了。

下面看看效果(不好意思,图没做好,不动请在新窗口中打开):

好了,到这我们就基本打通主程序和 App Extension 的相互通信了,是不是也很简单呢?

最后,一个小提醒

由于通知中心的界面是一大块 UIVisualEffectView ,并且具体参数调整过,所以插件的背景色最好保持透明,主要文字颜色最好是白色,次要文字的颜色最好是 lightTextColor,这样能适应毛玻璃下的 Vibrancy 效果。

今日面板每个插件的高度计算和 UITableView 自适应高度的计算方式一致,如果你没有设置 preferredContentSize,或者把它设为 CGSizeZero 了,就表示你想采用自适应高度,那么系统就会根据你设计的 Auto Layout 来确定适合的高度。如果你想这么做的话,直接参考 UITableViewCell 在 iOS 8 以后自适应高度的方式即可。

 
 

揭秘 iOS App Extension 开发 —— Today 篇的更多相关文章

  1. 关于报错:'sharedApplication' is unavailable: not available on iOS (App Extension) - Use view controller based

    最近在看Extension相关知识的时候,自己写了个小demo 发现[UIApplication sharedApplication]这个方法敲不出来了, 总是报错:'sharedApplicatio ...

  2. iOS9中找不到XXX.dylib 与 is unavailable no availabel on ios (app extension) - use view controller 的解决办法

    在 iOS9 中现在找不到 XXX.dylib 了,比如libz.tbd  如果要用到 libz.dylib,可以用下面的办法,来自 Stack Overflow. Go to Build Phase ...

  3. iOS - App Extension 整体总结

    一.App Extension的介绍 App Extension可以让你扩展你APP的自定义功能和内容,使用户可以在与其他应用或者系统进行互动的时候去使用它.app extension即为本文所说的e ...

  4. 开发外包注意事项——iOS APP的开发

    1. APP外包的流程是怎样的? 一般外包的项目都需要经常这几个流程: 1)需求沟通:双方沟通项目的需求,对项目的可行性进行分析 2)工作量评估:在确认了项目的需求后,外包团队对项目的价钱和进度进行评 ...

  5. iOS App Extension入门

    转自简书:http://www.jianshu.com/p/8cf08db29356   iOS 10推出了很多新功能,其中有几个高调的变化:通知栏更加实用,电话可以防骚扰,iMessage变得更加有 ...

  6. 开发外包注意事项二——iOS APP的开发

    目前我的方式是按时间算. 首先这得建立在双方的信任基础上. 以我做过的Case为例: 首先会和客户一起评估需求: 1. 哪些功能是最为重要的 2. 哪些功能是可以删除的 3. 用什么策略保证APP的出 ...

  7. 不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native

    [源码下载] 不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native 作者:web ...

  8. APP定制开发:APP软件开发的语言和开发环境

    APP软件开发是移动互联网开发公司常开发的一种手机应用系统,对于刚刚进入APP软件开发领域的新手来说,选择什么编程语言和需要什么开发环境来开发APP软件是常遇到的问题.下面亿合科技小编来为大家分享下: ...

  9. 征服恐惧!用 Vim 写 iOS App

    我们都知道 Vim 和 Emacs 都是文本编辑器中的上古神器,你也许用 ctags,cscopes 配合 Vim 完成过大型 C 或者 C++ 的开发,你也许配合过其他插件,完成过 JavaScri ...

随机推荐

  1. 基于c/s架构的远程登陆服务的步骤。

    1:上/下位机安装相应的服务程序.(确保内核支持该服务)2:上位机(作为服务器端)配置能够给下位机访问目录的所在地,及其读写权限.3:在/dev目录下创建该服务其所需要使用的虚拟文件设备,同时按照该服 ...

  2. php PDO getlastsql写法

    php PDO getlastsql写法有些时候 运行失败需要查看 sql语句 原型有没有语法错误 这个时候就用 下面的函数就是把问号替换成 值 就可以看到原型了<pre>function ...

  3. html5不能播放视频的方法

    html5不能播放视频的方法H5不能播放视频的方法 格式工厂转换成 AVC 注意音频流 采样率和比特率 设置低一点 不然播放会卡住 还有点击播放必须要click 不要用touchstart没效果的

  4. 使用火狐浏览器模仿手机浏览器,附浏览器HTTP_USER_AGENT汇总

    HTTP_USER_AGENT用来获取浏览页面的访问者在用什么操作系统(包括版本号)浏览器(包括版本号)和用户个人偏好. 改变浏览器的这个参数就可以伪装成相应的浏览器. User Agent Swit ...

  5. 【笔记】nginx部署静态网站

    安装nginx 本地到官网下载,然后把压缩包传到服务器上 安装三个依赖 apt-get install libpcre3 libpcre3-dev apt-get install zlib1g-dev ...

  6. java编程思想第四版第十一章习题

    第一题 package net.mindview.holding.test1; import java.util.ArrayList; import java.util.List; /** * 沙鼠 ...

  7. MySQL如何永久解决由dos编码格式导致MySQ的显示乱码

    MySQL如何永久解决由dos编码格式导致MySQ的显示乱码 Ⅰ.新建文件 changeCode.txt Ⅱ.粘贴下面代码(作用:将默认的GBK(936)修改为UTF-8(65001)) Window ...

  8. hdu 5901 Count primes (meisell-Lehmer)

    Count primes Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tot ...

  9. nyoj 24-素数距离问题 (素数算法)

    24-素数距离问题 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:21 submit:71 题目描述: 现在给出你一些数,要求你写出一个程序,输出这 ...

  10. 基于.NetStandard的简易EventBus实现-基础实现

    一.问题背景 最近离职来到了一家新的公司,原先是在乙方工作,这回到了甲方,在这一个月中,发现目前的业务很大一部分是靠轮询实现的,例如:通过轮询判断数据处于B状态了,则轮询到数据后执行某种动作,这个其实 ...