2021 App ServicesSystem Services
WWDC21 · 21 min · App Services / System Services
Send communication and Time Sensitive notifications
Learn more about the evolution of notifications on Apple platforms. We’ll explore how you can help people manage notifications within your app, including how you can craft meaningful moments with interruption levels and Time Sensitive notifications. And we’ll introduce you to communication notifications, providing a richer experience for calls and messages in your app through SiriKit. To get the most out of this session, we recommend having experience creating local and remote notifications, as well as some familiarity with SiriKit intents.
Watch at developer.apple.com ↗Code shown on screen · 12 snippets
Notification Action Icons
// Setting up notification actions with icons
let likeActionIcon = UNNotificationActionIcon(systemImageName: "hand.thumbsup")
let likeAction = UNNotificationAction(identifier: "like-action",
title: "Like",
options: [],
icon: likeActionIcon)
let commentActionIcon = UNNotificationActionIcon(templateImageName: "text.bubble")
let commentAction = UNTextInputNotificationAction(identifier: "comment-action",
title: "Comment",
options: [],
icon: commentActionIcon,
textInputButtonTitle: "Post",
textInputPlaceholder: "Type here…")
let category = UNNotificationCategory(identifier: "update-actions",
actions: [likeAction, commentAction],
intentIdentifiers: [], options: []) Notification Interruption Levels
// Interruption levels
let enum UNNotificationInterruptionLevel : Int {
case passive = 0
case active = 1
case timeSensitive = 2
case critical = 3
public static var `default`: UNNotificationInterruptionLevel { get }
} Passive Notification: Local
// Interruption levels
// Local notification
import UserNotifications
let content = UNMutableNotificationContent()
content.title = "Passive"
content.body = "I’m a passive notification, so I won’t interrupt you."
content.interruptionLevel = .passive
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: "passive-request-example",
content: content,
trigger: trigger) Passive Notification: Push
// Interruption levels
// Push notification
{
"aps" : {
"alert" : {
"title" : "Passive",
"body" : "I’m a passive notification, so I won’t interrupt you."
}
"interruption-level" : "passive"
}
} Time Sensitive Notification: Local
// Time Sensitive
// Local notification
let content = UNMutableNotificationContent()
content.title = "Urgent"
content.body = "Your account requires attention."
content.interruptionLevel = .timeSensitive
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0, repeats: false)
let request = UNNotificationRequest(identifier: "time-sensitive—example",
content: content,
trigger: trigger) Time Sensitive Notification: Push
// Time Sensitive
// Push notification
{
"aps" : {
"alert" : {
"title" : "Urgent",
"body" : "Your account requires attention."
}
"interruption-level" : "time-sensitive"
}
} Notification Content Providing
// New UserNotifications API
@available(macOS 12.0, *)
public protocol UNNotificationContentProviding : NSObjectProtocol {}
open class UNNotificationContent : NSObject, NSCopying, NSMutableCopying, NSSecureCoding {
// ...
@available(macOS 12.0, *)
open func updating(from provider: UNNotificationContentProviding) throws
-> UNNotificationContent
// ...
} Communication Notification: Incoming message
// Create a messaging notification
// In UNNotificationServiceExtension subclass
func didReceive(_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
let incomingMessageIntent: INSendMessageIntent = // ...
let interaction = INInteraction(intent: incomingMessageIntent, response: nil)
interaction.direction = .incoming
interaction.donate(completion: nil)
do {
let messageContent = try request.content.updating(from: incomingMessageIntent)
contentHandler(messageContent)
} catch {
// Handle error
}
} Communication Notification: Incoming call
// Create a call notification
// In UNNotificationServiceExtension subclass
func didReceive(_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
let incomingCallIntent: INStartCallIntent = // ...
let interaction = INInteraction(intent: incomingCallIntent, response: nil)
interaction.direction = .incoming
interaction.donate(completion: nil)
do {
let callContent = try request.content.updating(from: incomingCallIntent)
contentHandler(callContent)
} catch {
// Handle error
}
} Communication Notification: Outgoing message
func sendMessage(...) {
// ...
let intent: INSendMessageIntent = // ...
let interaction = INInteraction(intent: intent, response: nil)
interaction.direction = .outgoing
interaction.donate(completion: nil)
} Communication Notification: INPerson
// Create INPerson
let person = INPerson(personHandle: handle,
nameComponents: nameComponents,
displayName: displayName,
image: image,
contactIdentifier: contactIdentifier,
customIdentifier: customIdentifier,
aliases: nil,
suggestionType: suggestionType) Communication Notification: INSendMessageIntent
// Create INSendMessageIntent
// In your notification service extension
let intent = INSendMessageIntent(recipients: [person2],
outgoingMessageType: .outgoingMessageText,
content: content,
speakableGroupName: speakableGroupName,
conversationIdentifier: conversationIdentifier,
serviceName: serviceName,
sender: person1,
attachments: nil)
let interaction = INInteraction(intent: intent, response: nil)
interaction.direction = .incoming Resources
Related sessions
-
20 min