System Frameworks • iOS, macOS, tvOS, watchOS • 37:59
Push and locally scheduled notifications can provide people with timely information and provide them with the ability to take appropriate actions in response. Hear about the new APIs to schedule, respond to, and manage delivery of notifications. Learn how to write an extension to decrypt and augment push notifications before they are displayed.
Speakers: Kritarth Jain, Julien Barlerin
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript has potential transcription errors. We are working on an improved version.
Good morning everybody and welcome to our session, Introduction to Notifications. I'm Kritarth Jain an engineer on the iOS Notifications Team, and today I'll be joined by my colleague Julien for the later half of the session. Now the team's been working really hard over the last one year to give you guys a great release for notifications for iOS X and we're really excited to share it with you today.
We're going to start out by doing an overview of notifications. And today we're existing a brand new framework for doing user notifications. As part of this, we're going to cover registration, content creation, scheduling these notifications, managing them, and action handling on these notifications. And lastly, we're going to introduce a brand new feature today called service extensions that we think you're really going to like.
But there's a lot more to cover with notifications in iOS X and we're not going to get to all of it in this session. So there's going to be an Advance Notification Session following this one right in this very room. So do make sure to check it out.
So let's begin by talking about user notifications. Now I'm sure all of you are familiar with what a notification looks like. This is how your application sends information to your app users when your app is not in the foreground. It's a push mechanism of sending information, versus a pull mechanism where your app user actively goes to the application to get the content or the information.
Now, you as app developers, have different ways in which you can send these notifications to the user. They can be visual alerts, where the notification rolls down from the top as a banner. You can do sound and vibration alerts associated with your notifications as well as badge the app icon. So that the user knows which application has data available for them.
Depending upon the user's context, there're different ways how they see that notification. If the device is unlocked the notification rolls down from the top as a banner. While the device is locked, the notification comes right on the user's lock screen. And if the user ever misses these notifications, they can always go to the Notification Center and see all the pending notifications waiting for them there.
So what are the different types of notifications that you as app developers can use for sending these notifications? Mainly there are two types. Local notifications and remote notifications, depending on their source of origin. So let's look at these individually. Now local notifications are the ones that are used by applications that are on the device. Examples of local notifications use time based triggers, or location based triggers, where your application schedules this notification with the system showing the notification to the user's device, and when the user handles this notification, your application gets a callback.
As I mentioned, examples of these can include task reminder alerts, calendar alerts, or location based triggers. Now, not all your applications are contained on the user's device. A lot of them have a server-side component as well, where your server-side application lives across the network on your servers. So to facilitate notifications for that we have remote notifications. Let's take a look at how remote notifications work.
The main piece involved in this exchange is the Apple Push Notification Service, or APNs for short. It's part of remote notifications. Your remote site application sends the notification payload to APNs, which then does a best-effort delivery of this notification to the user's device, showing them that notification and then forwarding your application to be handled when the user interacts with it.
Examples of remote notifications can be news alerts, where your server-side application gets the latest breaking news and then forwards all these notifications to the different devices on all the clients that have your application installed on their device. Instant messaging alerts as well where the database is managed on your servers, and when a new message comes in you just pass that notification along to the user's device.
Now remote notifications in turn have two different components, they can be either user-facing or silent updates. Now user-facing notifications, as the name suggests are the ones that are displayed to the user on the device. And by setting up your notification payload the right way, you can add this content to be shown to the user. As opposed to user-facing notifications, we also offer silent update notifications.
Now, these silent update notifications work where your notification payload includes the content available flag when this notification is received on the device, the system knows to wake your application up in the background to perform a background app refresh. So then your client-side application can go and talk to your remote server application and get the latest greatest content available so that the next time your application users come to your device they see the latest information available to them giving them a very good user experience.
So that was in a nutshell the different notifications, type of those notification that you can use. Now before we proceed, let's do a quick overview of the existing API for notifications that we have in iOS. Now, you use UI application for registering your application and then scheduling notifications that your application wants to send. This is part of the UI kit framework that I'm sure most of you are familiar with. However, there were some issues with the existing API. For example, there are different callbacks for local and remote notifications which could lead to the duplication of code.
There's also limited control. After your application has already sent the notification to the user and there's different support for notifications across the multiple platforms that Apple supports today. So we really wanted to address these issues, and more, and on top of that give you guys some great new features for really elevating the notification experience for your app users. So today we're really excited to announce a brand new framework for doing user notifications. Let's take a look at what's this new framework includes.
To start out, it has a very familiar API with feature parity with what exists today. So transferring your code from the existing API to the new framework will be very easy. We've also expanded the content options that you can set on the notifications for having richer notifications sent to your user. We've combined the code pack for local and remote notification handling so that you have lesser code for handling the notifications.
[ Applause ]
We've also simplified the delegate methods that your application gets now when the user interacts with actions on these notifications. We've also included better notification management. What this means is that your apps now have access to notifications that are either pending delivery or already delivered to the user, allowing you to remove as well update notifications. We'll take a look at all of this in more detail in the session. Starting in iOS X we now allow your applications to do in-app presentation of notifications.
[ Applause ]
So now, your apps get the exact same look and feel as the system supports right in your applications. You can now also schedule and handle notifications right to your extensions. And lastly, we've added extension points to notifications themselves, but more on that later. So what this new framework also allows us is to have a single notifications API across multiple platforms that Apple supports, including iOS, watchOS, and tvOS. Let's take a look at what this means individually for all these different platforms.
On iOS, we give the full support for managing and scheduling notification that the new framework supports. On watchOS, we continue the existing support of forwarding notifications from the user's device to their Watch, but starting with watchOS 3, we now let your WatchOS applications to do local notification on the Watch itself.
What this means is that your Watch does not have to be connected to your device, and your applications can still do notifications. For example, you have the workout application and the user of your application is out on a workout, but forgot their device behind. You can still send them notifications of when they meet their workout goals or when their workout time is up right on the Watch itself. For more information about how to do notifications on WatchOS we have a Quick Interaction Techniques for WatchOS session.
And continuing, for tvOS, we now give support to badging app icons for both local and remote notifications. This can be used in different ways. For example, if your application wants to let the user know the number of unwatched episodes they have, you can just badge the app icon with that number. Or for a turn by turn based game, if the user has a pending user turn, then badging the app icon lets them know that that's waiting for them.
So that's in a nutshell summary of what this new framework allows you to do on all these different platforms that Apple has. Let's continue and dive into notification delivery on iOS. How does your application actually send this notification to the user's device for them to see it? Well, even before you can do this, the very first step that your application needs to do is registration. Let's take a look at what registration means.
Now notifications are an interruption for the user. So it's very important you get the user's authorization and permission before you send them these notifications. So you can ask them permission for banners, sound alerts or badging the app icon and the very first time you do this the user gets prompted with this message. You need to do this registration for both local as well as remote notification. And performing this registration in code is as simple as calling request authorization on the UN user notification object associated with your application, passing it the right parameters that you want registration for.
However, do note that the settings that the user might approve right now are highly configurable in the settings menu per application. So your application users can always go back and turn these on or off depending on their preferences. In iOS X we now give you the ability to access these user settings in your application so that you can be smarter about the notifications that you want to send to the user depending upon their preferences.
[ Applause ]
But registration doesn't end here. For remote notifications, there's another step for token registration, which uses the existing API on UI application. So you register for remote notifications, you need a network connection so that the system can then go talk to APNs for this registration for your device and your application.
This token gets returned to your client-side application, which then you need to forward to your servicer-side application. Now this is important because this token needs to be included as part of the notification payload that your remote side application is passing through your APNs. Because this token acts as the key for identifying your device and the application to which it wants to send the notification.
So that was registration. Now your application is ready to start sending notifications to the users. So the first thing that you need to do after that is create the content of that notification. Now I'm sure all of you have seen the brand new notification looks that we've introduced with iOS X. We're really excited about what this allows you to do. To start with, we now show the title of your notifications in all iOS notifications.
[ Applause ]
We've also included an extra field for the subtitle so you can have more dexterity in the type of information you're sending to the user. And of course, there's the body of the content. Let's take a look at how to set this up in code. So it's as simple as creating a UNmutableNotificationContent object and setting the different properties on it, that's it.
For remote notifications, it's fairly similar. Your notification payload is structured as shown here, and again you set the different properties of your payload before sending it to APNs. However, that's not it for content, we decided to go one step further, and starting in iOS X we now let all applications do media attachments right in the notifications.
[ Applause ]
So now you can have much richer and colorful notifications that your users see. For more on media attachments, we'll be doing a walkthrough on how to set these up in the Advance Notifications Session. So now that your content is ready, the next thing that your app needs to determine is when it wants to send the notification. And for that there are triggers.
In iOS X we support four different triggers, mainly push, timer interval, calendar, and location based triggers. Now the push trigger is associated exclusively with remote notifications when your remote side notification sends the notification to APNs it arrives on the device associated with the push trigger, all the other triggers are the ones that are associated with local notifications.
Now, time interval based triggers lets you schedule a notification at a certain time interval starting from now. For example, if you wanted to send the notification in two minutes from now, or you want to send it every hour starting from now. This also lets you schedule the notification immediately by setting the time interval to zero.
Now as opposed to time interval based triggers there are calendar triggers that lets you set a notification at a specific date and time in the future. So you have more control of exactly when the notification gets sent. Example of this can be at a certain time tomorrow morning or repeating it on a certain day of the week at a certain time.
And lastly in triggers, we have location based triggers, which uses your devices absolute location, or its location in relation to Bluetooth beacons and determining if your device is entering or leaving the region you can send notification to the user. Examples of this is when the user is leaving their home and the device is leaving that proximity, or say that the user is at a grocery store and your application wants to send them a coupon for a discount.
So those are the different triggers that we have as part of this new framework. Now that your content's ready and you know when you want to send the notification, the next step left is scheduling the notification with the system. For local notifications this is as simple as calling addrequest on the UUserNotificationCenter object. Which then on the trigger the system then displays the notification to the user.
And for remote notifications, your service-side application passes the payload to APNs, which does a best effort delivery sending the notification to the user's device. So let's summarize this whole delivery mechanism that we've talked about so far. Your application starts out by registering with the system. Then it creates the content, determines when it wants to send the notification and finally schedules the notification with the system leading to the notification getting shown to the user's device. It's as simple as that. Let's take a look at the summary in code.
Start out by doing registration, by calling requestAuthorization, you create the content of that notification. You create the trigger, in this example a simple time interval based trigger, and then you package all of this in a UNNotificationRequest object, passing a unique identifier, which will be important we will talk about later in this session. And then you schedule this notification with the system, completing the notification's delivery.
So, so far we've talked about what happens to a notification while your app is in the background and the user's not interacting with it, but what if your application is in the foreground when it receives a notification? And for this we do offer support for notification handling while your app is in the foreground.
Your application needs to implement the UNUserNotificationCenter delegate. And it has a method of willPresent notification, which lets you get the notification content as part of the UNNotification object passed with this method. Now this method also has a CompletionHandler, which must be called at the end of this function. One thing to note is that the CompletionHandler takes presentation options parameters.
Now, what this enables you to do is the in-app presentation that we talked about earlier. Let's see an example of how you can configure it up. So, say your application still wants to show the user the view as well as your sound alert while your application is in foreground. So this is as simple as calling the handler block with these different parameters. And if you don't want in-app presentation, you just don't pass any parameters. So that was notification handling while your application is in foreground.
Let's move on and talk about notification management. Now notification management is new with this framework and what this allows you to do is have access to notification that are pending delivery for your locally scheduled notifications, as well as access to delivered notification that the user might never see while local or remove notifications. Now you can also remove notifications that have already been sent to the user, as well as update and promote these notifications.
And important piece of notification management is the request identifier. Now, in the summary you saw that the request identifier is set on the notification of the request object. And for remote notifications there's a new request header the APNs collapse id that you need to set on your payload. The system uses this request identifier to know which notification you're requesting to be removed or updated. Let's take a look at notification management with an example.
Say your application wants to send notifications for a game, and it wants to send notifications for the start time of the game. So you start out by creating your UNNotification request and scheduling it with the system, but say that the game was cancelled. So this is as simple as calling removePendingNotification Request, passing it the exact same game identifier that you created for the initial notification. But what if the game time was updated? Then you create a new request, giving it the exact same identifier for the initial request, setting the new trigger time and just scheduling it with the system. And this in turn leads to updating that notification.
Let's continue this example for delivered notifications and talk about score updates. Again, you just start out by creating this notification request and sending it to the system. But say that the wrong score was updated, then you can simple remove that notification by calling removeDeliveredNotification giving it the same identifier.
And what if the score gets updated which of course is a very common case for games. So all you can do in this scenario is create a notification request, giving it the same identifier, passing it the new score content, and then simply scheduling it with the system. Now, what this means, let's take a look at it as an example, say that notification was already there for initial score update. So by calling update, as I showed in code, what this leads to is that that notification gets updated right in the notification list, replacing the original notification, so that you're not cluttering the user's notification list at all.
[ Applause ]
And you can use this in multiple ways for aggregating information that is right for your applications. So that was notification management, it really gives your applications a lot of control on the notifications that have been sent to the user. So so far in this session we've talked about how your application sends these notifications to the users. But what about the other side of this exchange? Notifications are very intractable in the form of default actions as well as custom actions that your applications can set on them. So, to talk about notification actions let me invite my colleague Julien to continue this session. Thank you.
[ Applause ]
Hi everyone. I'm Julien. I am a software engineer in the Frameworks QA Team. Kritarth showed you the web flow with the current user notifications framework from registration up to the time when notifications are delivered to the device. So now let's talk about the actions that the user can take on the notifications. There are three types of actions that your applications can be aware of.
The first one is the default action. It is when the user opens your app from a notification. This can be done when the device is unlocked and the user receives a notification, they can tap on the banner, which will open your app. It can also be done from the lock screen when the user swipes from left to right, as well as in the Notification Center when the user swipes down to present the Notification Center, they can tap on any of your notification to open your application.
Now the second type of actions are custom actions. And they are within the actionable notifications. We introduced actionable notifications in iOS 8 and they provide the user a quick way to execute an action directly from the notification without the need of launching your app. Now these custom actions, they appear as buttons with customizable title below the notification content. In iOS 9 we introduced text input actions so that the user can for example quickly reply to a message of directly from the notification.
And these custom actions can be either background or foreground. A background action will dismiss the notification and give you a short amount of time in the background to process that custom action that the user selected. On the other hand, a foreground action will dismiss the notification and launch your application in the foreground so that you can process that custom action.
Now these custom actions are available on both iOS and watchOS. So first, let's take a look at what it looks like on iOS. Here we have an example of an iPhone 6S. On this device, the user can use 3D touch to expand a notification. When they do so the custom actions will appear below the notification content. And some of these actions, as you can see can be text input actions so the user can quickly reply to a message.
Now on watchOS, same thing, the custom actions, appear below the notification content, and some of these actions can also be text input actions. And on the watchOS, you have the opportunity to provide some suggestions that the user is likely to choose for your text input action. Now for more information about notifications on watchOS you can attend the Quick Interaction Techniques for watchOS Session later today.
So now that we've talked about what the custom actions look like. Let's first talk about how you can register your custom actions and then present them to the user. So for registration, the first thing you will need to do is to create an action object. You give it a unique identifier, as well as a title. The title will appear on the customizable buttons that we previously saw. Action will be by default background action, but you can also provide some option such as if you want it to be a foreground action.
Now, all your actions they need to be associated with categories. The category requires a unique identifier. You give it all the actions you want. You can also provide now some intent identifiers, for more information about intents, you can attend the Introducing SiriKit Session. There are also some options that you can provide for the category. We will talk about one of them in a few moments. Now, once you've created all your actions and all your categories, the only thing you need to do is to register them to the UNUserNotificationCenter object associated with your application.
Now let's talk about how you can present these custom actions to your user. You can do so from both remote and local notifications. So first for remote notifications, the only thing you need to do is to set a category identifier in the APS dictionary of the remote notification payload. Now this identifier needs to match one of the identifiers for the categories you previously registered. For local notifications you just need to set the category identifier on the mutable content that you created. Same thing this identifier needs to match the identifier that you [inaudible] before.
Now let's talk about the third type of action that your app can be aware of is the dismiss action. Now the dismiss action is new to iOS X and it is when the user dismisses a specific notification. You could use this if, for example, you have a calendar application and let's say you send a remote notification to your user about an upcoming meeting. The user looks at the notification and decides to dismiss it. When in this case you might want to stop sending other remote notifications to other devices of this user since they have seen the notification already.
Now, how can the user actually dismiss the notification? Well they can do that on the lock screen by swiping from right to left, and tapping on the Clear button. They can also do that from the Notification Center by swiping from right to left as well, and taping on the Clear button which will dismiss the notification.
Now since this is not the common case you will need to update for it. So remember earlier when we talked about the different categories that you could register, we talked about some options, this is one of them, the customDismissAction option. So let's look at the code we used earlier to register our category. The only thing you need to do here, is simply add the customDismissAction to the options of this category and your app will receive the actions when the result dismisses specific notification with this category.
So let's summarize the actions that we talked about today. The first one is a default action, when the user opens your application from the notification. The second one where the custom actions within actionable notifications to provide a quick way for the user to execute an action directly from the notification. And finally the third one is the dismiss action, it is new to iOS X and it allows you to know when a user dismisses a specific notification.
[ Applause ]
Now let's talk about how you can actually handle the responses from these actions in your application. So until now we had several methods based on if the user opened the app from a notification, or if we had custom actions or text input actions, or if it was from a remote or a local notification.
Well now with our new user notifications framework, we have a single method to do that and it is part of the UNUserNotificationCenter delegate protocol. The method you will need to implement is didReceive response with CompletionHandler. Now let's take a closer look at the response object and what you can do with it in your application.
Your response object has an action identifier, which can either be the default, the dismiss action, or any of the custom actions that you created. It can have a user text property in case if it was a text input action. It can also have a notification object with the request object and the identifier of the notification as well as the trigger and the content. Based on the type of trigger you can figure out if it was from a local or a remote notification. So this is all with the new user notification framework, you can handle your responses of actions.
Now, let's talk about remote notifications. This is your current workflow, the workflow with remote notification that we saw earlier in this session. You have your service identification, which sends a remote notification to payload to Apple push notification service. And then it is delivered to the device and shown to the user. Now, maybe some of you are in a situation where you have your server side application and you communicate to your iOS application maybe using some end-to-end encryption.
Well, wouldn't that be great if you could use that same end to end encryption for your remote notification as well? Well for that in iOS X we are introducing the service extension. So now we are going to talk about what the service extension is and then how you can actually implement it in your application.
Now the service extension is a non iOS extension available on iOS X, which means it runs in the background. And its main purpose is to augment or replace the content of visible or remote notifications before they are displayed to the user. So let's take a look again at your current workflow for remote notifications. So you have your server-side application, you send a payload to Apple push notification service and then it is sent to the device.
Well, now with the extension, you're able to modify the content between the time you sent it from your server-side application and the time it is displayed to the user on their device. As you can see in this example, I did a title, as well as a subtitle, and I modified the body of the notification.
Now a few more details about that service extension. You will get a short execution time, which means this is not for long background running tasks. And in case you fail to provide some updated content in a timely manner, you will get a fallback method. In case you still fail to provide some updated content, we will show the original remote notification that you sent to the user. Now some potential uses of that you could use end-to-end encryption for your remote notifications and you could as well add some attachments to your remote notifications to make them even richer. Now there will be a detailed example on how to do that in the Advance Notification Session.
Now let's talk about how you can actually implement this new service extension in your application. The first thing you would need to do in your Xcode project to add the new target. You can use the template, which is located under the application extension section. And it is known as the notification service. Now this template has one main class. So we are going to take a look at a simplified version of it.
So this class, is a subclass of the UNNotification service extension and it has two main methods. The first method is didReceive with ContentHandler. Now this method will give you the current request which has the identifier for the notification as well as the content. Then we have the ContentHandler. You will need to call this ContentHandler when you want to present the notification to your user, and you need to provide some content for it.
Now, the second method is service extension time will expire, and this will be called if you cannot provide updated content in a timely manner. So now remember if you fail to call the ContentHandler in this method, we will show the original remote notification content that you sent. So now let's talk about how you can actually trigger this code from a remote notification.
Here, we have a very simple example of remote notification payload with an alert. And as you can see we have a new key, the mutable content key. Now, you will need to use this key to let the system know that you want the service extension to be launched to update the remote notification content.
You do not need to use this key every time, only use it when you actually want to replace the content of the notification. Now you can see that I also added some encrypted content of my own. So let's take a look at some code, which will be able to process this remote notification payload.
So you can see here we have our didReceive( request method, and the first thing I do here is I decrypt the encrypted content of the remote notification payload. I then create a MutableNotificationContent object and I assign the body of this notification with the decrypted content that we previously set. And finally we call the ContentHandler to present the notification content to the user. Now, this is how simple it is to implement the new service extension in your application.
[ Applause ]
Now let's recap what we've talked about today. We saw an overview of notification with local and remote notifications. We showed you the new user notification framework, where is available on iOS, watchOS, and tvOS. We talked about how you can register for notifications, as well as how you can create your content. How you can schedule your notifications, either local or remote.
We also talked about the new management that you can do on the pending and delivered notifications. And then we talked about the different actions that the user can take on your notifications and how you can handle the responses of these actions within your application. Finally, we presented the brand new service extension which allows you to augment or replace the content of visual remote notifications before they are displayed to the user. For more information, you can visit this link on developer.apple.com.
We will have some related sessions. There is an Advance Notification Session right after this one, we strongly encourage you to attend this session if you are interested in notifications. There is also if you want more information on notifications on the Watch you can attend the Quick Interaction Techniques for watchOS Session. Thank you everyone.
[ Applause ]