UserNotifications in Swift 3 (Part 2)

In iOS development, Apple provides a framework called UserNotifications. This framework assists with the delivery and handling of local and remote notifications. Examples of these types of notifications include notifying users of when to leave for an appointment (I get these an hour before I tutor a student) or if an important news article has been posted (I also get these from the NYTimes).

In my last blog post, I detailed the differences between local and remote notifications and walked through the steps in creating a local notification. In this post, I will discuss UNNotificationContentExtensions, what they do and how to incorporate one in your app.

UNNotificationContentExtension presents a custom interface for a delivered local or remote notification. — Apple Documentation

With UNNotificationContentExtension, you can customize the interface of your notification. If you want to change the way your notifications appear to the user, you will want to use UNNotificationContentExtension. Before, you had to use the system notification templates but now developers can create their own!

For this blog post, I will be creating a Friends TV character quiz. When a user clicks a button, a notification will be displayed with a Friends quote and a user will be given three choices of Friends characters — Ross, Chandler, and Joey.

Before We Begin

If you haven’t read my first blog post on UserNotifications, I advise you to do so. For this Friends quiz notification app, I have already created a new project and added the necessary UserNotification code to my AppDelegate.swift file:

In Storyboard, I made sure that I set up my UI, which consists of two imageViews, a button, and a label.

In ViewController.swift, I created outlets for my responseLabel and my friendImage imageView. I also created an action for when the button is tapped. In this action function, I created notification content, a notification trigger, a notification request and added the request to the notification center.

Lastly, make sure that you set the VC as the delegate and implement the delegate methods:

Now, let’s get to work on customizing this notification!

Step 1: Create a new target

Make sure that you choose Notification Content Extension.

I called mine NotificationViewController.

When this alert appears, click “cancel” — we’re not using this scheme for building or debugging.

In your left navigation pane, you’ll notice a NotificationViewController has been created with a NotificationViewController.swift file, a MainInterface.storyboard file and a Info.plist file. These files correspond to your notification.

Line #16 — the notification automatically comes with a label and outlet. You can delete this if you wish.

If you click on the MainInterface.storyboard, you’ll see the default notification UI.

Let’s fix the UI later.

Step 2: Define the attributes of this notification extension.

Change the UNNotificationExtensionCategory in the new Info.plist.

You’ll remember that we created the category in our AppDelegate.swift file.

In the Info.plist, change the UNNotificationExtensionCategory to “friendsQuizCategory”. This category needs to match the notification category name you want to display.

You’ll note that we have another attribute, UNNotificationExtensionInitialContentSizeRatio, which is a value between 0 and 1. This ratio identifies the aspect ratio of our custom notification interface. It has a default value of 1, which means that the interface will have a height equal to its width. If the ratio was 0.75, the interface would have a height equal to 0.75 its total width.

Step 3: Create the notification UI in MainInterface.storyboard.

For this, in the NotificationViewController.swift file, I deleted the label outlet that was on line #15. I also made sure to delete the “Hello World” label from the MainInterface.storyboard that corresponded with that outlet.

As you can see below, I added an imageView and a label. Make sure to constrain both to the view. Note that I changed the content mode for my imageView to Aspect Fit. You can set a default image to the imageView if you want.

Use assistant editor to create an outlet for this imageView. I called it friendsImage.

Step 4: Share your assets with your NotificationViewController target.

Click on your Assets folder and select both check boxes under target membership. These checks ensure that both your viewControllers will be able to access your images.

Step 5: Set the proportional vertical size of the notification in viewDidLoad( ).

If you don’t set a proportional vertical size, your notification will have a very skewed height.

Step 6: Set up any initial content of your notification.

If you want to display any content, such as changing the text of your answerLabel. Here, I changed the title to “How Well Do You Know Your Friends?”

This didReceive(_:) method which is called whenever an app gets a new notification. The UNNotification parameter is used to access all of the content of the incoming notification. Keep in mind that this method can be called more than once if your app keep receiving notifications when the interface is open.

Step 7 & 8: Implement the didReceive(_:completionHandler:) method and call its completion handler.

The didReceive(_:completionHandler:) method is called when the user taps on any of the notification actions. Be sure to call its completion handler to dismiss the notification when you have handled its action and are able to forward the action to the app (if needed). The UNNotificationResponse object is what is determines which action the user has selected.

As I mentioned in the last paragraph, the completion handler takes a UNNotificationContentExtensionResponseOption which is an enum with three cases: doNotDismiss , dismiss , dismissAndForwardAction . doNotDismiss is used when you have handled your notification action within the notificationViewController and you want the notification interface to stay on the screen. dismiss is used when you have handled your notification action within the notificationViewController and you want the notification interface to close (be removed from the screen). dismissAndForwardAction is used when you want to close the notification interface and let the appDelegate (or wherever your notification actions are) handle the action.

And there you go, you’ve just made your own customized interface for a notification!

Here’s what it looks like:

You can view my code here.

Resources:

UNNotificationContentExtension — Apple Documentation

Presenting Notifications Using a Custom Interface on iOS — Apple Documentation