iOS 10 最重要的变化可能就是通知 API 的重构了。本文用一个简单闹钟的例子介绍了 User Notification 的 API 变化和新功能。
《iOS 10 day by day》是 shinobicontrols 公司编写的系列博客,介绍开发者需要了解的 iOS 10 新特性,每周更新。本系列翻译(文集地址)已取得官方授权。目录点此。仓薯翻译,欢迎指正:)
Shinobicontrols 为 iOS 和 Android 开发者提供高性能、响应式的 UI 控件 SDK,尤其是图表方面的控件。 官网 : shinobicontrols.com twitter : @shinobicontrols
简介
很久以前,开发者就可以在 iOS 里预约本地通知了,但是之前的 API 缺乏细粒度的控制能力。幸运的是,苹果在 iOS 10 中改善了这一点,发布了新的 UserNotifications
框架。这个框架在处理本地通知及远程推送方面的 API 丰富了许多,同时写法更加简便。
本地通知(local notification)是用 app 来预约的通知,例如:提醒你带午饭的闹钟。而远程推送(remote notification)一般是服务器发起的,传到苹果的 APNS 服务器上,APNS 再推送到用户手机上。例如:推送给所有用户,告诉他们 app 发布新版本了。
实例工程
工程是用 Xcode 8 Beta 6 建的
我们用一个简单的闹钟 app 来介绍新的 UserNotification
框架,一个用户可以预约提醒的 to do list。到时间后,闹钟每 60 秒提醒一次,直到用户手动取消为止。跟之前一样,代码放在 github 上。
每个小喇叭的图标表示一个预约好的提醒,而被红色斜杠划掉的小喇叭表示这个事项不需要提醒。
我们还会添加让用户对通知做出响应的功能:
UI 部分
UI 界面上就是一个简单的 tableView,显示用户的 to do list。没什么可说的。
提醒事项的数据类型是这样定义的:
1 2 3 4 5 6 7 8 9 |
class NagMeTableViewController: UITableViewController { typealias Task = String let tasks: [Task] = [ "Wash Up", "Walk Dog", "Exercise" ] // 待续 |
我们的 tableView 就是一个提醒事项的列表,点击 cell 上的小喇叭按钮会调用一个闭包。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// 续上 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "TaskCell", for: indexPath) as! TaskCell let task = tasks[indexPath.row] cell.nameLabel.text = task // 显示 cell 上提醒/不提醒的图标 retrieveNotification(for: task) { request in request != nil ? cell.showReminderOnIcon() : cell.showReminderOffIcon() } // 点击按钮时调用闭包 cell.onButtonSelection = { [unowned self] in self.toggleReminder(for: task) } return cell } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return tasks.count } } |
为了判断用户是不是当前『正在被提醒』,我们要调一个 retrieveNotification(for: task)
方法,待会再详细说。如果存在 notification 对象,说明用户要求提醒这个事项。
当点击 cell 上喇叭按钮的时候,会调用一个 toggleReminder(for: task)
方法,我们也放在后文介绍。这个方法里就是预约提醒的神奇魔法。
请求用户授权
在预约提醒之前,需要先向用户请求通知的授权。在 app 启动时调用如下代码:
1 2 3 4 5 6 7 8 |
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { UNUserNotificationCenter.current().requestAuthorization(options: [.sound, .alert]) { granted, error in if granted { print("Approval granted to send notifications") } } } |
调用的结果是会显示一个弹窗,询问用户是否允许我们的 app 发送通知。闭包的 granted
参数表示我们是否取到了权限。这个弹窗只会显示一次,不过之后用户也可以在设置里进行更改。
你会发现,User Notification
框架大量的 API 使用了 completion block。这是因为向 UNUserNotificationCenter
发出的请求大部分都是在后台线程上异步执行的。调用 current()
方法会让框架返回一个供我们 app 使用的 notification center 单例对象,而我们所有的预约通知、取消通知都要通过这个单例对象来实现。
创建通知
创建、添加通知的过程实在有些冗长,我们把代码分解成几部分,一步一步来看:
1 2 3 4 5 6 7 8 |
/// 为 task 创建一个 notification,每分钟重复一次 func createReminderNotification(for task: Task) { // 配置 notification 的 content let contenton-sy">) { // 配置 notification 的 content let contentwww.shinobicontrols.com/" target="_blank">shinobicontrols 公司编写的系列博客,介绍开发者需要了解的 iOS 10 新特性,每周更新。本系列翻译(文集地址)已取得官方授权。目录点此。仓薯翻译,欢迎指正:)
Shinobicontrols 为 iOS 和 Android 开发者提供高性能、响应式的 UI 控件 SDK,尤其是图表方面的控件。 官网 : shinobicontrols.com twitter : @shinobicontrols 简介很久以前,开发者就可以在 iOS 里预约本地通知了,但是之前的 API 缺乏细粒度的控制能力。幸运的是,苹果在 iOS 10 中改善了这一点,发布了新的
实例工程
我们用一个简单的闹钟 app 来介绍新的 每个小喇叭的图标表示一个预约好的提醒,而被红色斜杠划掉的小喇叭表示这个事项不需要提醒。 预约提醒/取消提醒
我们还会添加让用户对通知做出响应的功能: 取消提醒
UI 部分UI 界面上就是一个简单的 tableView,显示用户的 to do list。没什么可说的。 提醒事项的数据类型是这样定义的:
我们的 tableView 就是一个提醒事项的列表,点击 cell 上的小喇叭按钮会调用一个闭包。
为了判断用户是不是当前『正在被提醒』,我们要调一个 当点击 cell 上喇叭按钮的时候,会调用一个 请求用户授权在预约提醒之前,需要先向用户请求通知的授权。在 app 启动时调用如下代码:
调用的结果是会显示一个弹窗,询问用户是否允许我们的 app 发送通知。闭包的 你会发现, 创建通知创建、添加通知的过程实在有些冗长,我们把代码分解成几部分,一步一步来看:
|