这篇文章主要记录了在制作 Today Widget 时的一些思考,如果想要知道如何创建一个 Today Widget,可以参考下面的文章:


在制作 Extension 的过程中还是遇到了一些坑,这里做一些记录。

Extension 的本质:相当于是一个独立的小 App,它可以做到通过 group 的方式和主 app 共享数据。

对于 Today widget 的开发实际上还是比较简单,可以当做是制作一个独立的页面,拉拉 outlet、action 之类的,然后响应数据更新界面,响应动作执行跳转等等。但是这里最大的疑问是数据共享的问题。

从文档中可以知道,想要让主 app 和 extension 之间共享数据,需要通过一个共享文件目录进行共享。这个共享目录通过指定一个 group id 来获取。

NSUserDefaults 共享数据

1
2
let userDefaults = NSUserDefaults(suiteName: "group.extension.vito")
userDefaults?.setObject(title, forKey: "title")

共享目录

1
2
3
let fileManager = NSFileManager.defaultManager()
let containerURL = fileManager.containerURLForSecurityApplicationGroupIdentifier("group.mycontainer")
let storeURL = containerURL?.URLByAppendingPathComponent("db.sqlite");

现在知道了如何在共享区域保存数据,但是什么时机来保存数据呢? 一种方式是将应用的数据和 extension 的数据放到共享容器中,这样主应用和 extension 都可以访问到全部的数据。这样的好处就是可以保证 extension 和主应用中显示的数据可以是完全一致的,因为访问的数据就是同一份数据。但是貌似在现在的版本中共享容器中的数据会在手机重装系统后丢失,这似乎是一个 bug:

Background Fetch 机制联想到 extension 的共享数据刷新

Today widget 也是有 Background fetch 机制的,在func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!)方法中就是接收到后台刷新的方法。设备会在认为合适的时间调用这里的代码。

有了后台刷新机制,我们可以就可以很方便的刷新共享区域的数据,比如在主应用中的 background fetch 代码中执行写入数据的代码,设置 background fetch 的时间间隔为一天。这样可以让 extension 每一天显示的数据都是新的。这种方式可以说是比较简单省事,又能达到预期效果的实现方式。 缺点是:由于backgroud fetch 的刷新时机实际上不是很准确的,就有可能会有一些小的延迟等情况,而且用户也可以在系统的设置应用中关闭其它应用的 background fetch 功能。

iOS UITextView 输入内容实时更新 cell 的高度

这篇文章介绍了在一个动态数据的 table view 中,cell 根据 text view 内容的输入实时改变 cell 和 table view 的高度。自动计算 cell 高度的功能使用 iOS 8 才支持的自适应 cell,如果你还不知道 iOS 8 自适应 cell, …… Continue reading

iOS 8 自适应 Cell

Published on November 13, 2014

iOS 8 HealthKit 介绍

Published on October 30, 2014