3D Touch on Notifications provides users with access to media attachments and live content. See how your app can take advantage of this new functionality to provide a rich interactive experience within the notification itself.
Welcome to Advanced Notifications.
I'm Michele, and today we will be talking about a few things
about new notifications in iOS 10.
We'll start with the new notifications user interface.
We'll go over a little bit of an overview,
and we'll see what changed in iOS 10.
Then we'll see how to use media attachments
in the new notifications, and, last, we'll see how
to customize the user interface for user notifications in iOS 10.
Let's start with the overview of the user interface.
User notifications in iOS 10 have a beautiful new design.
You see here the new lock screen
with beautiful animations and raise to wake.
Here is a banner.
You see they are much more legible.
They have more content.
They show title, subtitle, and this is notification center,
and notifications look the same in all three [inaudible] places.
In iOS 8, we introduced Actions Notifications
where you can add actions to your notifications
to make them more interactive and allow the user to deal
with that much more quickly.
In iOS 9, we introduced Quick Reply
to enhance actionable notifications
so you can even allow the user to respond with text
that they type to your notifications.
In iOS 10, notifications are much more powerful
because notifications now are more important to our device
as we interact with them all the time.
They are a very important way we interact with the device,
and a very important way the user interacts
with your applications.
So in iOS 10, you can press on notification,
and notification will expand
and show a much more detail specialized user interface
for your application, and it's dedicated to your content.
It shows more detail, and it's more useful to the user.
The user can also tap on the actions,
and the user interface can update and show what changed
and the effect of the action that they just used.
Calendar, which just a simple example.
We also have Find My Friends, for example,
that when a friend shares their location with you,
you see their location immediately in notification
so you can see how late they're going to be for your meeting.
We also have notifications for Photo Sharing.
If you shared a photo on iCloud, you can see the photo directly
in the notification without opening the app,
and you can like it or comment on it without opening the app
to look at the, at the picture.
At last, messages.
This is not all of it.
Messages support Quick Reply starting in iOS 8,
but you could only see one message,
and you can only type one response.
Now you see the entire conversation
when you open the notification, and you can respond to it,
you can wait for your friends to respond, and you type,
can type more responses.
This is the power of new notifications in iOS 10.
But is this was all there was to it, I wouldn't need to stay here
for half an hour and show you all the new notifications
in iOS 10.
So the most important feature I want talk to you about today is
that everything I just showed you is implemented
with the new API's that we are expand, exposing in iOS 10
so you can do exactly the same things that we've done
and add all the same features to your own applications
and your notifications.
The first thing you can do is media attachments.
You know, one of the most frequent notifications I receive
by my friends are pictures that they're sharing or videos.
So it's really important that we have the content
that was shared [inaudible] notifications
so I can see it more quickly without having
to open the app and download it.
But the problem is that, as you know,
push notifications are delivered with push payload,
and even if we increase the size last year to 4 kilobytes,
that's not nearly enough to send an entire picture,
even if it's a small one that we include in the notification.
So how do we do that?
We use the new service extensions
that we introduced earlier today in the previous presentation.
So to do, to download the attachment
in the service extension, you have to set your notification
to be mutable, as you see here in the payload.
I send a mutable content flag, and then you add a reference
to the attachment that you want to send with notification.
In this case, I use a simple URL,
but you could also use a identifier
that your app knows how to download from your own servers.
After you've done this, and the notification is delivered
to the device, the system will run your service extension.
In the service extension,
you can download the attachment anyway you want.
Perhaps you can use an URL session
so that the system helps you manage resources.
And then the notification is delivered
to the user with the attachment.
Let's see it, a little bit of code on how to do this.
This is a very basic example of my service extension.
At the top, I implemented the didReceive request
withContentHandler, and this is called
when the notification is received,
and I have to download my attachment.
I download my attachment, again, for maybe using the URL session
or other techniques that you prefer,
and when I have the file downloaded locally,
I can create a notification attachment object.
When I created the object, I added notification content,
and I pass it onto the system to be delivered to the user.
After I've done this, this is my notification
with a beautiful picture visible immediately to the user
without waiting for it to download
or without having to open the app.
And you see the notification suite attachments support
actionable notifications to.
So you can like or comment this, this picture directly from here.
So media attachments, a quick recap.
They support local, every [inaudible] notifications.
We only talked about local here.
We only talked about remote because local ones are easier.
You just create the notification attachment object
when you're scheduling the notification, and you're done.
Attachments support images, audio, and video,
and the system will provide, customize UI
for this three types of content.
You download the attachment in the service extension,
but you have to remember
that the service extensions has limited amount of time
that it can run, and file sizes are also limited
because these are meant to be sent with the notification.
They're not meant to deliver the entire content to the user.
So you may want to send a scaled-down version
of the image, and then download the full resolution one
when the user opens the app.
Or you may want to send a short video clip
if you're sending a video, and then download the full video
when they open the app.
When you downloaded it, you add it to the notification,
and at this point, the system takes over
and manages the file for you.
You don't need to worry about the file anymore.
The system moves it to a separate location
and handles all the data.
Oh, yeah, I almost forgot.
Of course, we support GIFs.
So attachments are pretty cool,
and they provide a very rich interface for notifications,
but at the beginning I said that you could implement everything
that I showed you with the new notifications, and calendar,
messages, and they were definitely not
They were using custom user interface,
and this is what we're talking about now.
To create a custom user interface,
you use the second extension point that we added
to our standard notifications,
and it's a NotificationContentExtension.
The NotificationContentExtension allows you
to add your own views, custom views.
You can draw anything you want, but the main,
most important limitation is
that there is no interaction with your views.
They don't receive touches.
The user cannot tap on them.
But notifications are still interactive
because you can use notification actions,
and the extension can handle those actions,
and we'll see later how to do it.
So I said that we can implement the same things
that the system is doing.
Let's start by seeing what calendar is doing,
and then we'll see how to do the same thing.
This is a calendar notification.
You see at the very top there's a header
with the notification icon that you can tap to open the app,
the application name, and the dismiss button.
This is standard UI that the system provides
to all notifications.
Underneath the header, there's the custom content,
and this is where your notification extension
This is where you draw your content.
You show all the extra details that you want to the user.
And underneath these, there's a default content
that the system shows.
This shows the content that was delivered with the payload.
This was what was visible until iOS 9 in the notification.
And at the very bottom, there are actions that a user can tap
and interact in notification.
When the user taps on them, the user interface can update
and show what happened.
So let's see how to make one of these ourselves.
We'll start with a party invite.
Parties are fun, and we're going Thursday, right.
This is the basic notification that will be displayed
by the user when you just send a push notification,
and it's pretty similar to what you expect.
Let's see how to expand this
and show custom user interface like we wanted.
The first thing you want to do is to create a new target
in your application, and you do that by using the template
that Xcode provides,
the NotificationContentExtension template.
This template will create three files in a new target.
A view controller, main interface storyboard,
and the info.plist where you can set
up customizables for the extension.
This is the view controller
for the NotificationContentExtension.
As you see, it's just a UI view controller subclass.
It's a regular view controller that you use as you're used to.
It also implements the NotificationContentExtension
protocol, and this is what tells the system that you want
to use these view controller for the notifications.
This protocol has only one required method.
The required method is didRreceive notification,
as you see here, and this method is called together
with the view controller life cycle method calls
when the notification is delivered to your notification.
To your extension.
So when the user expands the notification,
you will receive all the view controller calls
and these one in addition.
So you can receive the notification object
and update your UI and show different things.
The, the next thing you want to do is tell the system how
to find your content extension.
Content extensions, you use the same notification categories
that you use to register notifications actions.
In this case, I use the event invite
for my party invite invitation,
but extensions can also be associated
with multiple categories in case you want to use the same UI
for different types
of notifications that may be similar.
In this case, I'm using the event-invite or event-update.
They could be very similar UI's.
So I can just use the same, different categories
because they may have different actions.
So I set up everything.
I have my view controller.
Now I want to add some custom views to it to draw my own UI.
It's a very controller.
I added some labels in my storyboard
that I'm not showing here, and I'm,
when I receive the notification, I'm extracting the content
to have the information I need, and I'm setting the content
on the labels that I just created.
You see that I also have some custom information additional
to the standard one that comes with the payload because I want
to show something more than the standard payload for displays.
In this case, I'm showing the location
because it's pretty important to know where the party is.
And this is my notification now.
You see that I have some custom content.
I draw my own UI with my custom labels, different styles,
but these notifications has two problems.
The first problem is that this content is too big.
I don't need all that extra space.
It's all empty.
I have much smaller content to display.
The second problem is that the default content is duplicated.
I don't need it because I'm already displaying the same
information up top with my custom style.
But we can fix both of these problems.
Well, let's fix the first, the second one first
because it's easier, and this is an additional attribute
in your info.plist, and you can just set default content hidden
to yes to hide the default content.
The system will not add that anymore.
The second problem was the size of my notification,
but since it's just the view controller,
I can resize it the way I'm used to resizing view controllers.
In this case, I'm setting the preferred content size,
but you can set the constraints without the layout.
You can use the storyboard, and they will both work.
And after fixing these two issues,
this is my notification now.
It looks much better.
It's the right size that I wanted.
There's no duplicate content,
but did you see there was another problem now.
When the notification was presented,
it was not the right size.
So the system had to animate a resize the notification
to show it the right size.
Let me show it to you again.
See? We could make it better.
The reason this happens is that the system needs
to know the size of your final notification when it starts
to display it so you can do the right animation.
But your extension is not yet running
when the system starts presenting the notification.
So you need to tell the system in advance before any
of your code runs what size you want to be at the end.
But the problem is that these notifications run
in different devices
with different sizes in different context.
So the way we do that is that we set a content ratio,
content size ratio.
So these, this defines the ratio of the height and width
that you want to use for your content.
Now this may, of course, not always be possible
because you may have content of different sizes.
You don't know what content you're receiving.
You still want to display all of it.
So sometimes this may not be possible, but if you can,
figure out a size that works for your notifications.
This is the way to do it.
And the result after I've done this is this new notification
that now present it directly
at the right size from the beginning.
So let's review what we have done so far.
We wanted to do a custom notification UI.
We may, we started with these custom UI.
That's pretty basic, but has all my custom content has additional
information that was not in the payload,
but it was the wrong size.
So we fixed the presentation size
by using the initial content size ratio.
And then we fixed the duplicated content
by setting the default content type hidden flag,
and we went from the beginning to this.
This looks better than when we started.
Still not great, but I do have an appointment
that is unlocked today to fix it.
But I also know another trick to make notifications look nicer.
We can add pictures.
Pictures are always nice, especially on party invitations.
So we can use the same media attachments
that we used earlier also in NotificationContentExtensions.
Since they're added to the notification content,
you can access them inside your content extension.
So when you receive the notification [inaudible]
notification method, you can extract the attachments
from your content.
As I mentioned earlier, the attachment is managed
by the system, and it's moved to a separate location.
This means that it's outside of your sandbox.
So you need to tell the system that you want to start using it
and tell the system when you're done.
When you have access, you just use it as a file.
In this case, I'm adding it to my image view.
And here's my notification now.
You can tell this guy's ready to party.
This is much nicer than the one we started with,
and it's our own custom UI.
We want, we wanted to show additional information
to the user, and we added that.
We wanted to add a picture.
We have that, too.
Well, we missed the next step.
We want to make this interactive.
We want to implement the actions.
Let's do that now.
Default actions by default work the same way
as you're used to since iOS 8.
They are delivered to the app.
When the user taps on the button,
the app receives the [inaudible] request,
and the notification gets dismissed immediately.
This is pretty convenient because it's a behavior
that you often use, and it's pretty simple to implement,
but sometimes you want to show the user the effect
of the action for, like, in the example
of the calendar invitation.
That when the user tapped accept,
the content highlighted the event that I just accepted.
And you can do that in your NotificationContentExtensions.
You do that by intercepting the action
in the notification extension.
When you do that, the action is delivered to the extension
and it can decide to delay the dismissal of the notification.
So it has time to handle the action, update the UI,
and dismiss when it's done.
This is very simple, and you do it
with the second method inside the NotificationContentExtension
This method is optional.
You don't need to implement it if you don't need
to intercept the actions, but if you do implement it,
it means that you have to handle all the actions
that are in that notification.
You cannot handle one and not look at the other ones.
So when you receive the notification,
you can send a response of your server
to update the information on the server.
When you receive the response from the server,
you update the UI saying that the user is going
to the party, of course.
And when it's done, you can dismiss the notification.
So that the interface was updated before dismissing it.
In case you want to still forward the action
to your application, you can do that, too.
If you want to do additional handling,
or you want to keep the code in, all in the same place,
you just call completionHandler with a different parameter.
And what happens when we do this is that we receive notification,
we tap on that, and we can update the UI,
and we dismiss later.
So you saw in my example code that we implemented the accept
and decline action, and we have a third one at the bottom.
Because sometimes when you're responding
to a party invitation, you want to see,
we want to tell your friends how excited you are to go
to the party or how upset you are that you can't go.
So you tap on the comment action.
The comment action is a texting production,
like the ones we introduced in iOS 9, and you use it
in the same way, except with the new, awesome new framework.
This is a texting production.
A tiny bit of newer PI on this.
You can set the place holder in the text field,
and when you created the action, you can add it to your category
so that it's displayed with notifications.
So when the user taps on the comment button,
the text will display.
Now since this is an action like the others ones,
you can handle it in the same way.
So you can intercept it inside your extension
and handle it there.
Here's how you do that.
You receive the notification.
You check if it's a text input action.
You extract the text of the user typed and send it to the server.
And when you're done, you dismiss the notification.
And this is what happens.
You tap, type, and there's a problem again here
with this notification.
I want to respond to the invite, but there's only a send button,
and I can't say if I want to accept or decline.
So what we would like to do is to have the text field
but also two buttons so I can accept
or decline the invitation.
Something like this.
Would that work?
Well, there's no new API to do this, and there's no new API
because it already exists.
You can use the existing UIKit custom input accessory view API
to add your own custom into the text field to the notification.
To do that, the first thing you want to do is to say
that your controller can become first responder.
This tells both the UIKit system that it's part
of the responder chain and the notification system tells
that you don't want the standard text field.
Then you create your own custom inputAccessoryView,
in this case, like mine,
there was a text field and two buttons.
And then when I receive the response, the action,
the comment action from the user,
I can make it first responder so that the text field
and the keyboard appears.
I need to do both calls here
because the first one makes a view controller first responder.
So the text field appears,
and the second one makes the text field first responder
so that the keyboard appears.
You notice that in this case, I don't really, I'm not interested
in the fact that it's a textable action or not.
You can use regular actions because I'm going
to get the text from the user from my own inputAccessoryView.
So I have access to that UI.
And the result of this is that when you tap on comment,
now you can type your response
and actually respond to the invitation.
So this was all for NotificationContentExtensions.
There are some other small bits of the PI that you can come
and talk to us at the labs a little later in the week.
And what we learned today is how to use attachments in custom UI,
in Notification Content Extensions in iOS 10.
We learned how to download and add attachments to notifications
by using a service extension.
We learned how to do custom UI, fully custom UI
with your specialized content with the content extensions
that can use media attachments and can handle user interaction.
For more information about all of this,
there's a special page for this session.
We had a session earlier today that if you missed you can catch
up to learn about the new user notifications framework
and more details about the service extension.
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.