Gotchas When Implementing
iOS 10 Rich Notifications
Jonathan Samudio
Jonathan Samudio

Gotchas When Implementing
iOS 10 Rich Notifications

Jonathan Samudio, Senior iOS Engineer

Most of us are accustomed to Apple’s traditional notifications: a simple alert with a title and few lines of text. However, Apple took Notifications to the next level in iOS 10 by incorporating rich content – such as images, gifs, and videos.

While Apple provides documentation on how to setup and integrate Rich Notifications, there are a few “gotchas” that I’ve found while implementing them for the AMEX OPEN Forum App. More often than not these “gotchas” equate to extra time for development and testing that I hope this post relieves others of struggling through.

Provisioning

After you’ve convinced yourself to dive into Rich Notifications, your first step might be adding a Notification Service Extension or Notification Content Extension to your project. If you then run your project on your device, Xcode might start yelling for the correct provisioning profiles.

After adding the extension, Xcode creates a new bundle identifier that needs to be linked to the correct provisioning profile. A new App ID is needed to match the bundle identifier of the extension and then a new provisioning profile needs to be created with that App ID. Once the correct provisioning profiles are added to the project, the app should run on your device.

Legacy

The times are changing and so are notification frameworks. Apple’s release of iOS 10 included a new notification framework called UserNotifications to replace its now deprecated UIUserNotification subsets. If you’re blessed enough to be a developer that is working on a iOS 10+ application, then you do not need to worry about older iOS versions. For the rest of us, we need to ensure that we don’t throw the last remaining iOS 9 loyalists to the curb. The setup is logically identical, however writing two setups to do the same thing will take additional time to code and test. It’s recommended that developers and product teams supporting older versions of iOS scope Rich Notifications with additional time.

An example of where the two implementations differ is how they each request permissions to display notifications – you know, the little alert view that asks you to allow or disallow notifications. As shown in the code snippet below, the new UserNotifications framework adds the addition of a completion block. Upon completion, it’s fired when the user allows or disallows notifications, while the deprecated function doesn’t let you know when that action is completed.

@available(iOS 10.0, *)
    private func setupUserNotifications() {
        let notificationCenter = UNUserNotificationCenter.currentNotificationCenter()
        
        notificationCenter.requestAuthorizationWithOptions([.Badge, .Alert, .Sound],
                completionHandler: { (allowed: Bool, error: NSError?) in
            if allowed {
		 // NOTIFICATIONS ALLOWED HERE :)
                notificationCenter.setNotificationCategories(self.notificationCategories())
            }
        })
    }

Images

Chances are you chose to implement Rich Notifications for enhanced media content. Imagine the delight when a user receives a push notification and it contains a custom image that is related to their notification. How this magic happens can be described in two steps: updating the push notification payload and downloading the content. Whenever a user receives a notification, they receive a push notification payload which tells iOS how to present the notification. Adding the mutable-content key to the payload with a value of 1 will allow developers the ability to download the media-attachment.

{
    "aps": {
        "alert": {
            "body": "Hello There! Rich Notifications are Cool!!!",
            "title": "Rich Notifications"
            "subtitle": "Contains Cool Image"
        },
        "mutable-content" : 1
    },
    "media-attachment" : "http://some_domain/my_cool_image.png",
}

Apple provides a “Notification Content Extension” and a “Notification Service Extension” to handle updating the notification content. They both allow the developer to modify the notification; however, it’s the “Notification Content Extension” that allows developers to create a custom UI to present their Rich Notification.

Some Push notification services have frameworks to download the custom image easily,  however if you’re opting for a your own solution, writing the code may not be as trivial as it seems. A sample of the code to download an image can be provided in the link below. It starts by reading the push notification payload for the custom image URL. Then, the extension downloads the image to a temporary file location to be attached to the notification content once completed.   

Testing

At this point you’re probably dreaming of sending a push notification and seeing the custom attachment show up on your device. You click the magical “Run” button on Xcode and you send the notification. Waiting in anticipation you realize that despite an impeccable implementation, something went wrong.

Like any good developer knows, adding breakpoints can help isolate the problem; however, it’s not very clear how to set a breakpoint for a Notification. First, add your breakpoints in the Notification Extension – then run the application and select “Debug” -> “Attach Process by PID or name”. As shown in the image below, indicate the name of your extension as the “Process Name”. Trigger the notification and wait around 5 seconds as it takes time for Xcode to hit the breakpoint. Once a breakpoint in the extension is hit, it works just like any other breakpoint.

Possible Errors

After showing everyone that adding custom content to push notifications is a cool addition to any iOS app, the next step is to submit it to Apple. If you used CocoaPods in the the Notification Extension then there may be errors as shown below when submitting to Apple.

ERROR ITMS-90685: "CFBundleIdentifier Collision. There is more than one bundle with the CFBundleIdentifier value 'org.cocoapods.Alamofire' under the iOS application 'OPEN Forum.app'."

ERROR ITMS-90205: "Invalid Bundle. The bundle at 'OPEN Forum.app/PlugIns/OPEN Forum Notification Service Extension.appex' contains disallowed nested bundles."

ERROR ITMS-90206: "Invalid Bundle. The bundle at 'OPEN Forum.app/PlugIns/OPEN Forum Notification Service Extension.appex' contains disallowed file 'Frameworks’."

These errors are the result of using an older version of CocoaPods.  As described here in a CocoaPods Blog Post, updating to version 1.1.0+ should fix the extension issue.

Next Steps

Armed with the knowledge of what to look out for, developers should test the limits of what they can present with Rich Notifications. Less time debugging means more time programming, and more time programming means a better experience for our user. If you’re an avid smartphone user you know how amazing a well thought out experience can be. So go forth and build (Rich Notifications!) for the sake of the user.