UserNotifications框架简介

介绍

借助iOS 10,tvOS 10和watchOS 3,Apple引入了一个称为UserNotifications框架的新框架。 这套全新的API提供了一种统一的,面向对象的方式,可以在这些平台上使用本地和远程通知。 与现有的API相比,此功能特别有用,因为现在与本地和远程通知的处理非常相似,并且不再仅通过词典来访问通知内容。

在本教程中,我将介绍这个新框架的基础知识,并展示如何轻松利用它来支持应用程序的通知。

本教程要求您使用最新的iOS,tvOS和watchOS SDK运行Xcode 8。

1.注册通知

任何支持通知的应用程序的第一步都是向用户请求权限。 与以前的iOS版本一样,在使用UserNotifications框架时,通常的做法是在应用程序启动完成后立即执行此操作。

在使用任何UserNotifications API之前,您需要将以下import语句添加到访问框架的任何Swift代码文件中:

import UserNotifications

接下来,为了注册您的应用程序以接收通知,您需要将以下代码添加到AppDelegateapplication(_:didFinishLaunchingWithOptions:)方法中:

let center = UNUserNotificationCenter.current()
let options: UNAuthorizationOptions = [.alert, .badge, .sound]
center.requestAuthorization(options: options) { (granted, error) in
    if granted {
        application.registerForRemoteNotifications()
    }
}

最初使用此代码,我们获得对当前UNUserNotificationCenter对象的引用。 接下来,我们使用希望应用程序具有的通知功能来配置UNAuthorizationOptions 请注意,您可以在此处使用任意选项组合,例如, alertbadgesound

然后使用这两个对象,通过在我们的UNUserNotificationCenter实例上调用requestAuthorization(options:completionHandler:)方法来为我们的应用请求显示通知的授权。 代码的完成处理程序块向其中传递了两个参数:

  • 一个Bool值,表示用户是否授予了授权。
  • 一个可选的Error对象,如果系统由于某种原因而无法为您的应用请求通知授权,它将包含信息。

请注意,注册远程通知将调用与以前的iOS版本相同的UIApplication回调方法。 成功时, application(_:didRegisterForRemoteNotificationsWithDeviceToken:)将被调用,并application(_:didFailToRegisterForRemoteNotificationsWithError:)将失败被调用。

2.安排通知

在本教程的这一部分中,我们将完全专注于使用UserNotifications框架安排本地通知。 由于引入了新框架,因此远程推送通知的发送未更改。

在计划之前,本地通知由UNNotificationRequest类的实例表示。 此类型的对象由以下组件组成:

  • 标识符:唯一的String ,可让您将各个通知彼此区分开。
  • 内容: UNNotificationContent对象,其中包含显示通知所需的所有信息,包括标题,副标题和应用徽章编号。
  • 触发器: UNNotificationTrigger对象,系统使用它来确定何时将通知“发送”到您的应用。

首先,我们将研究可以为本地通知设置的各种类型的触发器。 UNNotificationTrigger类是一个抽象类,这意味着您永远不要直接创建它的实例。 相反,您将使用可用的子类。 当前,UserNotifications框架为您提供了三个:

  • UNTimeIntervalNotificationTrigger ,它允许在计划通知后发送通知一段时间。
  • UNCalendarNotificationTrigger ,无论通知是在什么时间UNCalendarNotificationTrigger ,它都允许在特定的日期和时间发送通知。
  • UNLocationNotificationTrigger ,它允许在用户进入或离开指定地理区域时发送通知。

以下代码显示了如何创建每种类型的触发器:

let timeTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 60.0 * 60.0, repeats: false)

var date = DateComponents()
date.hour = 22
let calendarTrigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)

let center = CLLocationCoordinate2D(latitude: 40.0, longitude: 120.0)
let region = CLCircularRegion(center: center, radius: 500.0, identifier: "Location")
region.notifyOnEntry = true;
region.notifyOnExit = false;
let locationTrigger = UNLocationNotificationTrigger(region: region, repeats: false)

使用以上代码,已创建以下触发条件:

  • 安排通知一小时后, timeTrigger将触发。 传递给UNTimeIntervalNotificationTrigger初始化程序的timeInterval参数以秒为单位。
  • calendarTrigger将每天每天晚上10:00重复触发。 通过修改传递给UNCalendarNotificationTrigger初始化程序的DateComponents对象的其他属性,可以轻松更改触发器触发的确切日期和时间。
  • 当用户到达指定坐标的500米以内(本例中为40°N 120°E)时, locationTrigger将触发。 从代码中可以看到,此触发类型可以用于任何坐标和/或区域大小,并且还可以在进入和退出区域时触发通知。

接下来,我们需要为通知创建内容。 这是通过创建UNMutableNotificationContent类的实例来完成的。 必须使用此类,因为常规的UNNotificationContent类具有对各种通知内容属性的只读访问权限。

以下代码显示了如何创建基本通知的内容:

let content = UNMutableNotificationContent()
content.title = "Notification Title"
content.subtitle = "Notification Subtitle"
content.body = "Some notification body information to be displayed."
content.badge = 1
content.sound = UNNotificationSound.default()

如果您希望获得完整的属性列表,请查看UNMutableNotificationContent 类参考 。

最后,我们现在只需要创建UNNotificationRequest对象并安排它。 可以使用以下代码完成此操作:

let request = UNNotificationRequest(identifier: "LocalNotification", content: content, trigger: timeTrigger)
UNUserNotificationCenter.current().add(request) { error in
    if let error = error {
        // Do something with error
    } else {
        // Request was added successfully
    }
}

最初使用此代码,我们通过将标识符,内容对象和触发器传递给初始化程序来创建请求对象。 然后,我们在当前UNUserNotificationCenter对象上调用add(_:completionHandler:)方法,并使用完成处理程序根据通知是否已正确调度来执行逻辑。

3.接收通知

使用UserNotifications框架时,处理传入的通知由您指定符合UNUserNotificationCenterDelegate协议的对象处理。 该对象可以是您想要的任何对象,而不必像以前的iOS版本那样是应用程序委托。

不过,需要注意的一件事是,必须在应用程序完全启动之前设置委托。 对于iOS应用程序,这意味着您必须在application(_:willFinishLaunchingWithOptions:)委托的application(_:willFinishLaunchingWithOptions:)application(_:didFinishLaunchingWithOptions:)方法内分配委托。 使用以下代码可以非常轻松地为用户通知设置委托:

UNUserNotificationCenter.current().delegate = delegateObject

现在已经设置了委托,当应用程序收到通知时,您只需要担心两种方法。 这两个方法都传递了一个UNNotification对象,该对象表示正在接收的通知。 该对象包含一个date属性和一个request属性,该属性可以准确地告诉您通知的发送时间,而request属性是前面提到的UNNotificationRequest类的实例。 从此请求对象,您可以访问通知的内容以及(如果需要)通知的触发器。 该触发对象将是前面提到的UNNotificationTrigger子类之一的实例,或者在推送通知的情况下,将是UNPushNotificationTrigger类的实例。

UNUserNotificationCenterDelegate协议定义的第一个方法是userNotificationCenter(_:willPresent:withCompletionHandler:)方法。 仅当您的应用程序在前台运行并收到通知时才调用此方法。 从这里,您可以访问通知的内容,并在需要时在应用程序中显示自己的自定义界面。 另外,您可以告诉系统使用各种选项来显示通知,就像您的应用程序未运行时一样。 可用的选项有:

  • 警报以显示系统生成的通知界面
  • 声音播放与通知相关的声音
  • 徽章,可在用户主屏幕上编辑您的应用的徽章

以下代码显示了userNotificationCenter(_:willPresent:withCompletionHandler:)方法的示例实现:

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    let content = notification.request.content
    // Process notification content
    
    completionHandler([.alert, .sound]) // Display notification as regular alert and play sound
}

UNUserNotificationCenterDelegate协议定义的另一种方法是userNotificationCenter(_:didReceive:withCompletionHandler:)方法。 当用户以任何方式与您的应用通知进行交互(包括关闭通知或从中打开您的应用)时,都会调用此方法。

该方法具有一个UNNotificationResponse对象作为参数传递给它,而不是UNNotification对象。 该对象包含代表已传递的通知的UNNotification对象。 它还包括一个actionIdentifier属性,用于确定用户如何与通知进行交互。 在取消通知或打开您的应用程序的情况下,UserNotifications框架会提供恒定的动作标识符供您比较。

以下代码显示了userNotificationCenter(_:didReceive:withCompletionHandler:)方法的示例实现:

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    let actionIdentifier = response.actionIdentifier
    
    switch actionIdentifier {
    case UNNotificationDismissActionIdentifier: // Notification was dismissed by user
        // Do something
        completionHandler()
    case UNNotificationDefaultActionIdentifier: // App was opened from notification
        // Do something
        completionHandler()
    default:
        completionHandler()
    }
}

请注意,对于这两个委托方法,在完成处理通知后立即调用完成处理程序是至关重要的。 完成后,系统便知道您已经完成了通知,并可以执行任何所需的过程,例如将通知放在用户的通知中心中。

4.管理通知

有时,您的应用程序用户可能会在您的应用程序未运行时收到多个通知。 他们还可能直接从主屏幕而不是通过通知打开您的应用。 在这两种情况下,都不会调用UNUserNotificationCenterDelegate协议方法。 使用本地通知时,有时您可能还希望删除计划的通知,然后再将其显示给用户。

因此,UserNotifications框架在当前的UNUserNotificationCenter实例上提供以下方法,以处理未处理的本地通知和尚未处理的已传递通知:

  • getPendingNotificationRequests(completionHandler:)在完成处理程序中为您提供一组UNNotificationRequest对象。 该数组将包含您已调度的所有尚未触发的本地通知。
  • removePendingNotificationRequests(withIdentifiers:)删除所有计划的本地通知,这些通知带有作为参数传入的String数组中包含的标识符。
  • removeAllPendingNotificationRequests删除应用程序的所有计划的本地通知。
  • getDeliveredNotifications(completionHandler:)在完成处理程序中为您提供了一组UNNotification对象。 该数组将包含为您的应用程序传递的所有通知,这些通知仍在用户的通知中心中显示。
  • removeDeliveredNotifications(withIdentifiers:)删除所有传递的通知,这些通知具有从用户的通知中心传入的String数组中包含的标识符。
  • removeAllDeliveredNotifications删除应用程序的所有已传递通知。

5.自定义操作通知

UserNotifications框架还使您的应用更容易利用iOS 8中引入的自定义通知类别和操作。

首先,您需要分别使用UNNotificationActionUNNotificationCategory类定义应用程序支持的自定义操作和类别。 对于您希望用户能够输入文本的操作,可以使用UNTextInputNotificationAction类,它是UNNotificationAction的子类。 定义动作和类别后,您只需在当前UNUserNotificationCenter实例上调用setNotificationCategories(_:)方法。 以下代码显示了如何轻松地在自己的应用程序中为消息类别通知注册回复和删除操作:

let replyAction = UNTextInputNotificationAction(identifier: "com.usernotificationstutorial.reply", title: "Reply", options: [], textInputButtonTitle: "Send", textInputPlaceholder: "Type your message")
let deleteAction = UNNotificationAction(identifier: "com.usernotificationstutorial.delete", title: "Delete", options: [.authenticationRequired, .destructive])
let category = UNNotificationCategory(identifier: "com.usernotificationstutorial.message", actions: [replyAction, deleteAction], intentIdentifiers: [], options: [])
center.setNotificationCategories([category])

接下来,当用户使用您的自定义通知动作之一时,将调用我们前面介绍的同一userNotificationCenter(_:didReceive:withCompletionHandler:)方法。 在这种情况下,传入的UNNotificationResponse对象的操作标识符将与您为自定义操作定义的标识符相同。 还需要注意的是,如果用户与文本输入通知动作进行了交互,则传递给此方法的响应对象将为UNTextInputNotificationResponse类型。

以下代码显示了此方法的示例实现,包括先前创建的操作的逻辑:

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    let actionIdentifier = response.actionIdentifier
    let content = response.notification.request.content
    
    switch actionIdentifier {
    case UNNotificationDismissActionIdentifier: // Notification was dismissed by user
        // Do something
        completionHandler()
    case UNNotificationDefaultActionIdentifier: // App was opened from notification
        // Do something
        completionHandler()
    case "com.usernotificationstutorial.reply":
        if let textResponse = response as? UNTextInputNotificationResponse {
            let reply = textResponse.userText
            // Send reply message
            completionHandler()
        }
    case "com.usernotificationstutorial.delete":
        // Delete message
        completionHandler()
    default:
        completionHandler()
    }
}

此外,如果您想利用本地通知的自定义操作,则可以在创建通知时简单地在UNMutableNotificationContent对象上设置categoryIdentifier属性。

结论

新的UserNotifications框架提供了功能齐全且易于使用的面向对象的API,用于在iOS,watchOS和tvOS上处理本地和远程通知。 它使在各种情况下安排本地通知变得非常容易,并且大大简化了处理传入通知和自定义操作的整个流程。

翻译自: https://code.tutsplus.com/tutorials/an-introduction-to-the-usernotifications-framework--cms-27250

你可能感兴趣的:(UserNotifications框架简介)