最近玩手机发现了widget这个app外的控件还是蛮有意思的,于是在上网查了一下资料,是iOS 8的系统开始开放的一个快捷显示操作功能,这个功能弥补了没有3D touch功能的iPhone。虽然网上百度可以查看到很相关的开发资料,但是我发现基本上都是Objective-C的例子,关于Swift开发的我仅仅只是看到了一篇(可能有一些我没看到),主要是都不够详细,作为一个新手的我,也为了让新手们少爬一些坑,我将详细为大家讲解如何玩转这个widget功能。附上图片

屏幕快照 2017-02-17 11.24.25.png
开发环境:Xcode 8.2.1
开发语言:Swift 3.0(以上)
1.第一步:如何创建widget
如何创建?在网上有已经有很多了,这里我还是给大家截图一下:

屏幕快照 2017-02-17 11.30.49.png

屏幕快照 2017-02-17 11.31.42.png
选择Today Extension ,点击Next ,项目中就会自动创建一个如下图所示的文件夹:

屏幕快照 2017-02-17 11.35.22.png
(这里的swiftWidget文件夹是我自己命名的)

屏幕快照 2017-02-17 11.37.32.png
里面有一个TodayViewController.swift、MainInterface.storyboard和Info.plist文件(里面的image的两个文件夹是我后来放的图片)
到这里就创建完成了!可以运行下看看效果(建议真机上运行效果更加)
2.第二步:界面UI布局
widget的UI布局,一般来讲以iOS 10为分界线,iOS 10和10以上是一种,iOS 8至iOS 10(不包含iOS 10)又是一种,如下图:

iOS 10及以上.png

iOS 10以下.png
主要是背景的不同,虽然widget也可以自定义背景色,但是最好还是用系统自带的!这里我给了两套UI。
编写UI界面布局有两种,这里要注意用纯代码编写需要修改widget文件夹里面的Info.plist文件里面的NSExtension的配置文件:如下
NSExtensionMainStoryboard:MainInterface(你的storyboard)这个是默认的

屏幕快照 2017-02-17 13.45.54.png
NSExtensionPrincipalClass:TodayViewController(你widget控制器的名称)

屏幕快照 2017-02-17 13.48.24.png
重点注意:(我自爬出来的坑)
用Swift开发(目前的swift3.0版本)widget的UI布局必须用storyboard拉取控件,也就是上面默认的,如果你用纯代码编写是不会有效果出来的(本人也是个纯代码控,这里Swift这个坑确实难搞,我经过数十次的尝试才发现这个bug。网上根本没有人记载,apple官方文档我也看不懂,问大神也不知道是怎么回事,爬坑的过程是痛苦的...。如果有大神知道如何用Swift纯代码来布局UI的话,迫切希望您能告诉我,我也收回说这是Swift语言的bug的话)。但是Objective-C两者都行,这里我只说Swift如何来写。

用storyboard来编写UI布局.png
具体如何给约束,还是你们自己去搞吧!这个不难!当然Swift虽说不能用纯代码来UI,但是用storyboard拉取控件定义的属性和方法还是必须要用代码来写的,要不然就不能开发widget了!^_^
对于如何使用两套UI,这个就要根据iOS 系统来做判断,改变image了!
3.证书申请:
如果要上架的,那么必须要申请证书了。我的这个demo一开始就用的证书运行的(本人强迫症,只要真机运行就要用证书)这里我就跟大家讲讲需要注意哪些事情:
因为widget是一个单独的控件,所有它是需要独立的bundle ID和证书的

widget的证书.png
当然主app的bundle ID也是一样的,但是两者不能相同的名字,这里我用的企业级证书申请的。
这里要注意的是widget是app的一个组件,要数据共享的话,这里涉及到一个叫做App Groups的id设置和申请:

BFF39167-B2C0-4E39-91A8-3489F6E2953D.png
注意主app的id和widget的id设置都需要打开App Groups这个功能,这里我只用widget的id的截图做示范:

widget ID的App Groups和主app ID的App Groups都需要开启.png
还需要与你申请的App Groups的ID和主app的ID相关联,如果你之前就已经申请了证书但是未关联的话,请编辑bundle ID,重新添加:

CB86CBB5-697E-4EE4-A491-C1C9DE02905A.png

选中申请的App Groups的ID.png
然后在Xcode中一定要重新更新证书,打开App Groups:

主app和widget都需要打开这里选中组件id.png

主app的App Groups.png
(一定能要更新证书后才能使用哦!因为苹果的证书在网站上更新后,在你的xcode中并没有更新,他会重新生成一个新的,需要你手动删除再添加)。
至此,证书和App Groups的添加完成。如果有报错,请仔细检查(你要相信,程序是不会故意报错的;有错误,一定是你那里没有做好,在自己身上找原因)。
4.数据共享和传输:
有了上面的App Groups的添加,我们就可以用代码进行数据传输和共享了。一般来讲,widget这个功能只是在手机上快捷显示的数据和操作的功能,你可以用你手机上的支付宝来进行测试操作一下。
这里我把代码截图出来,我用的UserDefaults来存储数据,在主app里面进行判断,打开相应的界面。

在TodayViewController里面进行相应的操作.png
注意因为widget是单独的控件操作,所以这么的点击widget上的按钮,跳转到主app,需要给主app一个URL Schemes:

主app的URL Schemes.png
然后在主app里面进行判断你存储的数据(这里要注意,iPhone的程序有两种情况,一种是在后台状态,一种是程序完全关闭状态),跳转相应的界面。说明一下,我上面的充电状态是我自己给的死数据,没有做相关的数据共享操作,自己思考解决,很简单的。如果有需要demo的,请在github下载:https://github.com/chenwupeng/CCwidget/tree/7f28c5f458a38cb174b7e038dc21db7a7710dcd6
总结一下,这次用Swift开发Widget,确实走了很多弯路,不过还好的是,从坑里爬起来了,也希望苹果能快点把这个坑填起来!在这里,希望我的这篇文章能对同行的你们有些帮助,如果发现有关swift开发的坑,尽量会帮大家指出来!
作者:氢色的气球
链接:http://www.jianshu.com/p/44112b7bddef
來源:
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。