Streaming is available in most browsers,
and in the Developer app.
-
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.
Resources
Related Videos
WWDC21
-
Download
♪ Bass music playing ♪ ♪ Kritarth Jain: Hi there and welcome to "Send communication and Time Sensitive notifications." I am Kritarth, an engineer on the Notifications team, and later I will be joined by my colleague, Kevin.
Notifications are a key component of the application experience and we will cover new ways to enhance them, along with elevating certain categories of notifications.
We will start out by covering some visual updates to notifications and how to augment them with new API.
Then we will do an overview of new management controls and how these are relevant to communication and Time Sensitive notifications.
Then we will focus on notification interruptions and cover new APIs to control them.
After which, we will hone in on the two types of notifications -- Time Sensitive and communication -- and cover ways in which these can be configured.
Let's begin by going over some visual updates to notifications.
Now, notifications have a new look with greater focus on the content and the associated media along with the application icon.
The rich notification presentation and accompanying actions have been updated to match the system style.
You can now associate notification actions with icons.
Iconography conveys what the action will do and provides visual context next to the action.
Here there are two notification actions -- like and comment -- and these are set on the custom notification category.
To add icons to these actions, create objects of type UNNotificationActionIcon with the image name, either for a system image or a template image.
Then provide these icons to the respective constructors for UNNotificationAction.
When a notification associated with this category is expanded, the actions are presented along with the icons that were provided for them.
Because notifications display the app icon at a larger size, provide a high-resolution icon with the application bundle.
Ensure content extensions continue to work with the new presentation and layout of the rich notifications, and adopt icons for notification actions to add more context.
Next, let's go over new notification management options.
There are new system controls which affect the delivery and interruption of notifications from applications.
These are notification summary and Focus.
Let's discuss notification summary first.
Notifications can now be delivered at scheduled times in the day as a summary.
This reduces the number of active interruptions from incoming notifications and presents them collectively at preset times.
All notifications delivered to the summary on a schedule are present in the notification list on the Lock screen.
Include media attachments with the notification content so there is a better chance for that notification to be featured at the top of the notification summary.
Adopt the new API to provide a relevance score for the notification content so the right notifications from the application get featured in the notification summary as well.
The other management tool relevant to notifications is Focus.
The device can be set in a particular Focus based on the activity or time of day such as Reading, Sleep, or Work.
When in such a configuration, the device will filter the presentation and interruption of notifications.
Focus configuration allows selecting people and applications that can send interruptive notifications.
For example, during the Work Focus, Mail and Messages are allowed to send notifications, along with direct communication from coworkers.
So notification summary and Focus control which applications can send interruptive notifications and when.
This allows better management of interruptions throughout the day.
There is opportunity for notifications to break through these management controls, but only if allowed to do so.
It is also possible for communication and Time Sensitive notifications to break through.
Next let's discuss how applications can control interruptions tied to notifications.
There is a new API for interruption levels as part of the UserNotifications framework.
There are four distinct interruption levels that are supported.
These are Passive, Active, Time Sensitive, and Critical.
Notifications with Passive interruption level do not alert or light up the screen, and do not break through system controls.
These notifications are delivered to the notification list silently and are available the next time the list is viewed.
Passive interruption should be used for notifications that do not require immediate attention to interrupt but should be seen eventually.
Some examples are dining recommendations and new episode availability.
Active interruption resembles the behavior that exists today, where notifications will play sound and vibrations and light up the screen.
These notifications will not break through system management of notifications.
This is the default interruption level.
Active interruption should be used for notifications that do not warrant interrupting if the system is configured not to be interrupted currently.
Some examples are sports updates and live stream video notifications.
Time Sensitive notifications alert just like active notifications.
These are special because they can break through system controls such as notification summary and Focus, if it has been allowed.
These notifications should only be used when it is relevant to actively interrupt, requiring immediate attention.
Some instances are account security and package delivery alerts.
Lastly, Critical interruption level is equivalent to the Critical notification support that exists in iOS 14.
Notifications with this interruption level actively alert, break through system controls, and also bypass the ringer switch on the device.
Because of this disruptive behavior, critical interruption will continue to require an approved entitlement.
Some use cases for critical notifications are severe weather and local safety alerts.
To support the new API in the UserNotifications framework, there is a new enum for UNNotificationInterruptionLevel with the different levels defined.
Set this interruption level while configuring the content object for the notification request.
Passive is set in this example.
If no interruption level is provided, then the default level is used.
For a push notification payload, provide a new key-value pair, with the key interruption level.
Here again, set the interruption level as passive.
When this notification is delivered to the device, it will be visible on the Lock screen without any interruptions, since it was configured as passive.
Another form of interruption tied to notifications is Announce.
Siri can announce notifications if there are compatible devices -- such as AirPods Pro and AirPods Max -- connected.
To get this announce behavior in iOS 14, notifications had to be tied to a category that requests the AllowAnnouncement option.
In iOS 15, the requirement for this category option is deprecated.
Now announce is supported for any notification while connected to a supported audio device.
Communication and Time Sensitive notifications will be announced by default.
While connected to CarPlay, communication notifications can be configured to announce automatically, making the experience more seamless.
Next let's focus on Time Sensitive notifications and how to configure them.
Time Sensitive notifications are those that require immediate attention.
Because of their importance, these can breakthrough system controls such as notification summary and Focus if allowed to do so.
An example of a Time Sensitive notification is one from Reminders about taking medication.
This notification is posted immediately and prominently, breaking through the Work Focus.
It is important to maintain trust when sending Time Sensitive notifications.
Do not overuse their interruptive nature and only use them when it is relevant to do so.
Know that there is an option to turn off Time Sensitive alerts or even all notifications from an application.
To configure Time Sensitive notifications, enable the associated capability via Xcode for your application.
Set the Time Sensitive interruption level on the notification request being posted.
For a local notification, the Time Sensitive interruption level is set on the content object.
For a push payload, set the interruption-level key with value as time-sensitive.
When delivered, this notification is posted prominently, highlighting the urgency.
Let's discuss communication notifications.
And to tell you all about them, let me hand over to Kevin.
Kevin? Kevin Harrington: Thanks, Kritarth.
I'm Kevin, an engineer on the Notifications team.
There's an importance for urgent notifications breaking through Focus and notification summaries.
Communications from people also warrant elevated notification delivery.
These communications can come in many forms, including calls and messages.
I will highlight a new API that allows your applications to signal what notifications are communications, and the people associated with those communications.
The importance of communication notifications is determined by user decisions.
Siri Suggestions helps inform these decisions, suggesting important people that should be allowed to interrupt.
As your user interacts with the device -- taking calls, joining FaceTimes, sending messages -- Siri learns who is a candidate to break through Focus and Notification Summaries.
In iOS 15, communication notifications get a richer user experience.
Most visible are the prominent avatars.
The title and subtitle are standardized.
It always includes the sender in the title, and in the case of group communications, recipients in the subtitle.
The title and subtitle text are localized and formatted for all devices, across platforms.
For example, watch prefers to show just first names for recipients of a group communication.
Siri will now announce the contents of communication notifications on supported devices including HomePod, AirPods, and CarPlay.
And Siri will provide suggestions to help prioritize these communication notifications.
People in your apps will get associated with people in Contacts.
These associations are shown as suggestions on notifications.
Once a user confirms a suggestion, Siri Shortcuts are available for tasks with those people in your app.
Siri will suggest relevant people to break through in the Focus configuration -- including those people associated with communications in your app.
To make these decisions on what is and isn't a communication, this new API lets you add SiriKit call and message intents to Notifications.
Intents are driven by common tasks.
Your app donates these intents when events happen, like placing a call or receiving a message.
From there, Siri provides shortcuts and suggestions based on these intents, like people in your apps to message from share sheet or to start a call from your app via Siri.
This new API associates these same intents with notifications to further integrate your apps into the Siri ecosystem.
Using SiriKit intents for communication notifications will increase engagement in your apps while maintaining consistency throughout your app, Siri, and system UI.
The intents that represent relevant communications are the StartCall and SendMessage intents.
The NotificationContentProviding protocol is the mechanism to associate intents with notifications.
On a NotificationContent object, call updating with a ContentProviding intent for communication treatment.
StartCall and SendMessage intents conforms to providing.
Communication notifications are delivered through Apple Push Notification service.
You need to update a NotificationContent object with a SiriKit intent in your app's NotificationServiceExtension.
SiriKit intents are local to the device, and thus must be serviced locally.
The service extension is for exactly these cases.
It is the place to customize the content of a remote notification before it is delivered.
You can also do this in your main app process for local notifications.
In your didReceive function, update the content of a push payload with an intent.
For messaging notifications, create a SendMessageIntent.
And for call-related notifications, use a StartCallIntent.
Create an interaction to tell Siri intelligence what is happening.
In a notification extension, the interaction direction is always incoming.
This is an event that is happening to the user; they are receiving the incoming call.
Next, you need to donate the interaction.
Donations also help the system make better suggestions in the future.
Update the content of your notification with the intent.
And finally, call the contentHandler with the returned intent.
Donations are required so Siri can learn from events that happen in your apps.
The interaction direction is always incoming for notifications.
For other SiriKit uses, the direction can be outgoing for actions initiated on the device, like sending an outgoing message or placing a call.
Only system objects that conform to content providing are supported.
Do not conform your objects to content providing.
To send communication notifications, enable the communication capability via Xcode for your application.
Support communication intents by adding intent types to your user activity types array in Info.plist or by implementing an intents extension.
Donate communication intents when the user takes actions in your app foreground, like when the users hits send after composing a message.
Siri then uses outgoing intents to better aide in who should be suggested to break through Focus and Summaries.
Same for Contacts suggestions.
For this feature, Siri only learns from outgoing intent donations, so Contacts are not cluttered by people not engaged with -- like spam callers.
The proper usage of communication intents is fundamental to an intelligent notification experience, and there are a few gotchas to cover.
Intent persons are the building blocks of SendMessage and StartCall intents.
Each and every parameter you populate provides a richer and more intelligent user experience.
Same goes with creating intents with intent persons; each and every parameter you populate provides a richer and more intelligent user experience.
Start using intents if you don't already.
Intents will provide more visibility to your app in notifications, share sheet, Contacts, and Spotlight.
And you can use SiriKit to offer Siri Shortcuts like sending a message or starting a call.
Get in the habit of donating intents for both incoming and outgoing interactions.
You might already be donating outgoing intents.
Start donating incoming StartCall and SendMessage intents in your service extension.
This is fundamental to the communication notification experience.
If your app doesn't already use a notification service extension, you'll want to add one.
Finally, put the pieces together by using the content providing protocol to decorate each notification you want delivered as a communication.
We've covered a lot in this session, from visual updates to communication notifications.
Here are a few takeaways.
Account for the new visual updates and management options and ensure that notifications work seamlessly with them.
Adopt interruption levels to have better control over how a notification interrupts in synergy with system controls.
Use Time Sensitive notifications when relevant to prominently interrupt and get automatic behaviors such as breakthrough and announce.
Implement and donate call and messaging intents to get the upgraded communication experience tied to notifications, along with breakthrough and announce behavior.
We can't wait to see all the new and amazing experiences you build around notifications.
We hope you all have a great WWDC! ♪
-
-
1:57 - 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: [])
-
8:19 - 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 } }
-
8:31 - 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)
-
8:47 - 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" } }
-
11:13 - 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)
-
11:20 - Time Sensitive Notification: Push
// Time Sensitive // Push notification { "aps" : { "alert" : { "title" : "Urgent", "body" : "Your account requires attention." } "interruption-level" : "time-sensitive" } }
-
15:20 - 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 // ... }
-
16:08 - 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 } }
-
16:20 - 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 } }
-
17:48 - Communication Notification: Outgoing message
func sendMessage(...) { // ... let intent: INSendMessageIntent = // ... let interaction = INInteraction(intent: intent, response: nil) interaction.direction = .outgoing interaction.donate(completion: nil) }
-
18:29 - Communication Notification: INPerson
// Create INPerson let person = INPerson(personHandle: handle, nameComponents: nameComponents, displayName: displayName, image: image, contactIdentifier: contactIdentifier, customIdentifier: customIdentifier, aliases: nil, suggestionType: suggestionType)
-
18:43 - 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
-
-
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.