主页 > 新体验 > 设计沙龙 > 技术调研
  • iOS 开发中,怎样用好 Notifications?(上)

    adinnet/2017-04-14 15:21/技术调研

    前言

    在 iOS 开发中,有这样一个场景:某件重要的事情必须立刻让用户知道,甚至不惜以打断用户当前操作为代价来强调这份重要性。这就是通知(Notifiations)。目前常用的框架为 UserNotifications,它主要用来在锁屏和应用界面通过弹窗来显示通知。另一个框架是 Notification Center ,以它实现的跨 object 通知以及原生的 KVO(Key-Value-Observing) 是 iOS 中观察者模式的主要实现手段。

    本文内容:

    • UserNotifications 介绍

    • 本地通知(Local Notifications)

    • 远程通知(Remote Notifications)

    • 观察者模式(Observer Pattern)

    UserNotifications 介绍

    UserNotifications 是 iOS 10 刚刚引入的全新框架。与以往版本的本地通知和远程通知分别处理不同,这次苹果把两者的 API 统一。从此以后,无论处理本地通知还是远程通知,都是用 UserNotifications 框架

    UserNotifications 的流程也十分简单,主要分以下 4 步:


    UserNotifications 流程

    • 注册

    通过调用 requestAuthorization 这个方法,通知中心会向用户发送通知许可请求。在弹出的 Alert 中点击同意,即可完成注册。

    • 创建

    如果是本地推送,则在 AppDelegate 中设置推送参数;如果是远程推送,则无需设置参数,推送的内容和触发时间都在远程服务器端配置。

    • 推送

    这一步就是系统或者远程服务器推送通知。伴随着一声清脆的响声(或自定义的声音),通知对应的UI显示到手机界面的过程。

    • 响应

    当用户看到通知后,点击进去会有相应的响应选项。如下图:


    例如 Instagram 这个 App ,用户看到它的通知后有3个选项:一是 Like , 点击之后就是给你朋友的照片点赞;另一个是 Quick Reply,点击之后可以评论照片;更后是 View Post,点击之后是进入 Instagram 主 App 进行照片浏览。用户不同的选择决定了之后的操作,笔者称这个过程是对 Notification 的响应

    本地通知

    因为通知是针对整个 App 级别的功能,所以一般在 AppDelegate 中完成注册和创建的过程。代码如下:

    /// 注册
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { accepted, error in
     if !accepted {    print("Notification access denied.")
     }
    }

    /// 创建
    func scheduleNotification(at date: Date) {
     /// 触发机制  let calendar = Calendar(identifier: .gregorian)  let components = calendar.dateComponents(in: .current, from: date)  let newComponents = DateComponents(calendar: calendar, timeZone: .current, month: components.month, day: components.day, hour: components.hour, minute: components.minute)  let trigger = UNCalendarNotificationTrigger(dateMatching: newComponents, repeats: false)

     /// 通知内容  let content = UNMutableNotificationContent()  content.title = "Tutorial Reminder"
     content.body = "Just a reminder to read your tutorial over at Soapyigu's Swift30Projects!"
     content.sound = UNNotificationSound.default()

     /// 传入参数  let request = UNNotificationRequest(identifier: "textNotification", content: content, trigger: trigger)

     /// 将创建好的通知传入通知中心
     UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
     UNUserNotificationCenter.current().add(request) { error in
       if let error = error {      print("Uh oh! We had an error: \(error)")
       }
     }
    }

    在创建过程中,有以下几点值得注意:

    • 触发机制。如果是时间触发,就用 UNCalendarNotificationTrigger;如果是地点触发,就用 UNLocationNotificationTrigger。

    • 通知内容。除了标题(title)、内容(body)、声音(sound)外,还可以添加副标题(subTitle)甚至是图片。添加图片的示例代码如下:

    /// 将图片添加到通知中if let path = Bundle.main.path(forResource: "Swift", ofType: "png") {  /// 通过本地图片 Swift.png 的路径创建 URL
     let url = URL(fileURLWithPath: path)

     do {
       let attachment = try UNNotificationAttachment(identifier: "Swift", url: url, options: nil)    /// 设置内容的附件,将图片传入
       /// 你可以传多个图片进入,但只会显示第一个图片
       /// 当然你也可以根据不同情况显示不同图片
       content.attachments = [attachment]
     } catch {
       print("The attachment was not loaded.")
     }
    }
    • Identifier。一个 App 可能有多种本地通知,它们之间是通过 Identifier 进行区分的。

    • 将创建好的通知传入通知中心。多个 Notifications 之间有先后顺序,它们排成队列在通知中心中。这里我们为了方便演示,删除了以前所有的通知。

    完成了注册和创建,我们只要在合适的时间让系统推送通知即可。代码中表现为在某个时间点调用scheduleNotification(date)。之后我们就可以看到相应的通知弹出:

    一般情况下用户会点击通知直接进入 App 查看。假如要实现在通知出现时快速操作,比如过10分钟再提醒我这样的选项,我们又该怎么做呢?这时候我们引入UNNotificationActionUNNotificationCategory

    • UNNotificationAction: 响应通知的单个具体操作。例如直接给相关推送信息点赞。

    • UNNotificationCategory: 响应操作对应的类别。相当于是多个 UNNotificationAction 构成的群组,表明一类响应操作。

    下面一段代码就是创立了一个 "Remind me later" 的 UNNotificationAction 响应操作,并将其加入到 "normal" 的
    UNNotificationCategory 类别之中。

    let action = UNNotificationAction(identifier: "remindLater", title: "Remind me later", options: [])
    let category = UNNotificationCategory(identifier: "normal", actions: [action], intentIdentifiers: [], options: [])
       UNUserNotificationCenter.current().setNotificationCategories([category])

    有了上面代码,当用户点击通知,我们就能看到相应的快捷操作。那么用户点击 “Remind me later” ,我们该如何在 App 中设置对应的操作,让系统在10分钟后再次推送响应通知呢?


    很简单,我们只要在UNUserNotificationCenterDelegate 协议中实现userNotificationCenter(_:didReceive:withCompletionHandler:)
    。当用户点击通知选项时,这个方法自动被调用。这里我们通过 identifier 来判断具体是哪一个选项被点击,再调用对应响应方法即可。

    extension AppDelegate: UNUserNotificationCenterDelegate {  func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {    if response.actionIdentifier == "remindLater" {      let newDate = Date(timeInterval: 600, since: Date())
         scheduleNotification(at: newDate)
       }
     }
    }



上一篇:iOS 开发中,怎样用好 Notifications?(下)下一篇:提高设计说服力!来学习这个腾讯内部的设计效果检验方法
400-021-8655
在线咨询
在线留言