2.5 Interactive Custom Notifications
In this lesson, I'll show you how to code creative and engaging interactions with the new content extensions in iOS 10.
1.Introduction2 lessons, 04:21
2.What's New in iOS 10?5 lessons, 32:38
3.Conclusion1 lesson, 00:51
2.5 Interactive Custom Notifications
Hi, and welcome back to what's new in iOS 10. In this lesson, I'm going to show you the new user notifications framework and how to create custom interactive notifications. With every new topic in this class so far, I'm going to create a new target first. This time it is going to be a Notification Content Extension, even though it doesn't want to show the full name. I'm calling it BirthdaysNotification since that's what I want to show. I'm not going to activate a scheme right now. What does this give us? Well, very little, a notification view controller and a storyboard with a single scene that isn't very pretty. Well. Since I'm already in here, let's just lay out how we want the final version to be. I'm going to remove the label and set the background to transparent again. Then I want an image view that will display a picture. We also need some constraints. Then I'm going to add a label that is on the bottom, also with the correct constraints. I'm going to center the label, make the font bold, and white, as well as setting a shadow so we can see it better on bright backgrounds. I'm also going to add a height constraint, or rather an aspect ratio constraint, which I will set to 3 by 2 so we can display a typical photo. Okay, after a little bit of adjusting it the way I want, It is now laid out properly. Now I need to connect the outlets. The label is still present from the sample. I just need to connect it. Then I need to create an outlet for the image view, which I call just ImageView. Okay, this is what our final notification will look like. But I jumped ahead a little bit because we should first be able to actually send a notification. I'm going to do this in the view controller of the main application. Here I have prepared a method that is hooked to a button in the UI already. I also prepared some properties to now randomly select the name and an image as well as some sample text. Let's get started with the image, which is going to be called an attachment in the context of user notification. Of course, Xcode doesn't know about this clause yet because I need to import the new user notifications framework. A UNNotificationAttachment has an identifier which I set to the name of the person. I also need an image URL for the image, and I can leave the options blank. Around this attachment, we need to have some content. It is going to be of type UNMutableNotificationContent. Attachment or not, you need to specify all your data here. I'm going to set the title, subtitle attachments, which has div 1. So let's wrap it in an array. And finally, a body. Alongside the notifications content goes a trigger. It is an abstract meta clause, that can either be a push notification trigger, calendar or location trigger, or what we want to use, a simple time interval trigger. To make it more interesting, I'm triggering the notification after one to ten seconds. I could also say it gets triggered repeatedly. We're almost there. The next object in line is a notification request object. It has an identifier and holds some content and a trigger, all the properties we just created. Now it's time to add this request at a current UNUserNotificationCenter. I'm also adding a completion handler that has an error object if adding this notification failed. If I do get an error, I'm going to print it. Unfortunately, just adding the notification is not enough. The app needs to properly handle it. Therefore, I'm switching to the app delegate and some prepared code. First of all, I'm going to make the app delegate, the delegate for the UNUserNotificationCenter. This can be done by adding the appropriate protocol and setting the delegate of the current UserNotificationCenter. This allows us to handle an incoming notification. Here we are using the UserNotificationCenter willPresent method to decide how we want to present a notification when the app is running. If the app doesn't have this method, it won't show notifications when in foreground. I decided that simply showing an alert is enough for our purposes. Like with Siri, we also need to ask our users to allow it to send notifications. In our case, we are asking for alerts and sounds. Okay, let's try it and run the app. As soon as it starts, we receive a request to allow notifications from the app. When I click on the button on the bottom, it will create a notification that pops up as an alert on the top. I can drag it down to show its full content. All the data we provided is presented to us, including the image. Note that this isn't our custom notification, it is the default from Apple. Now that we verified that the system is working, we can switch to the custom notification we created. Of course, a custom notification interface normally means you only want to show specific notifications with our special view. For this case, Apple provides an entry in the extensions info.plist to set the supported UNNotificationExtension category. I'm going to remove the default and call it birthdayNotificationCategory. Then we need to populate our view with the notification. This happens in the didReceive method. First, I'm going to check for an attachment in notification.request.content.attachments.- first. If there is one, I need to tell its url that we want to access it from the apps sent books. Then we can set the imageView.image to the contents of it. As a good citizen, I'm notifying the url that I stopped accessing it after I set the image. I also don't explicitly unwrap the path. Now that we set a category in the extension, we somehow need to add this category to our notification center. This will be done when starting the app. There is a special class for this purpose called UNNotificationCategory that has an identifier, some actions and other properties we don't use. The identifier is going to be the one from the info.plist. As for actions, let's start with a simple dismiss action. It is a UNNotificationAction with the identifier dismiss, the title Don't congratulate, and no options. Now that the category is created, the final step is to set it on the notification center. To associate the single notification with this category, we can set it on the notification content of the categoryIdentifier property. Before we can test it, I have to first build and run the main app. And then the birthdaysNotificationsExtension. Xcode will ask me in which app I want to run it, or I can choose the example app. Here is the notification, I can pull it down. Whoops, I messed up the constraints, and yes, you can do that with notifications also. I need to set it with constraints on the Image View. Also, I didn't set the label. When you have a look at the notification, you can see that there is a big white square before the image loads. This is an assumption iOS makes about the content. Within the info.plist, we can change that. There is also the possibility to remove Apple's default view that is below our custom notification with the UNNotificationExtensionDefaultContentHidd- enEntry. Now the content has the right format as it's expecting, and without a separate title below the image. Right now the notification is custom, but it isn't really intact of yet. Let's change that. The NotificationViewController supports another method that is called didReceive response. If the user presses a button, it will call this method for the action to be handled. I'm going to create an action in a second to congratulate the user which will change the label's text. I'm also going to dismiss the notification, but after a delay of two seconds. To do this I'm going to call async after and use the dispatch time clause for the delay. Within the block, I'm calling the completion handler with DismissAndForwardAction. Which means a method in the app will get called with the action identifier passed on. The way of adding the action is the same as with the dismissed one. I'm just using a different identifier and title. Then I need to add it to the categories action and we're golden. Let's give it a final try. First, I have to run the app again since I changed the code here, and then I can run the extension. And here we go. The notification shows and when I click Congratulate, the label changes and the notification gets dismissed. Awesome, with iOS 10, user notifications have become much more powerful, and much easier to use, in my opinion. In this lesson, I only scratched the surface. You can do much more with the new UNUserNotificationCenter.