Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
With the release of iOS-10, Apple introduces brand new frameworks to support notifications, be it local or remote. Customized notifications is what this release focussed on.
Without wasting any time, letâs just quickly jump on to the details.
Types of notifications
We can broadly classify notifications into 2 categories,
- Local notificationsâââapp configures the notification details locally and passes those details to the system, which then handles the delivery of the notification when the app is not in the foreground.
- Remote notificationsâââuse one of your companyâs servers to push data to user devices via the Apple Push Notification service(APNs).
Further in the article, weâll see how we can get hold of both the notification types. Letâs first start with the introduction to the very new notification framework that we can use to our cause.
Whatâs new in iOS-10 for Notifications?
With the release of iOS-10, Apple introduced 2 new frameworks to handle notifications,
- User Notifications Frameworkâââmanages both local and remote notifications.
- User Notifications UI Frameworkâââcustomize the appearance of the systemâs notification interface.
Weâll be using these 2 frameworks and some platform-specific APIs to configure our notifications.
Along with the frameworks, Notification service app extension was also introduced that allows modifying the content of remote notifications before they are delivered.
Apple also allowed customising the notifications UI though Notification content extension.
Is it too much to remember? Yup..surely it is. But, don't worry. Weâll see everything step-by-step along with the relevant code. Just take it easy..đ
First Step FirstâââConfigure it..!!
Request Authorization
To get our app notify anything, we need to know whether the person using it actually wants that at the first place. May be he donât like his phone ringing and displaying alerts all the time đ..or may be he actually want the updates but not that irritating sound..naahhh..!!!â ïž
So, first of all we need to take the permission from the one weâre going to notify. And thatâs pretty simple, just 2 lines of code and weâre done.
You need to write that code in AppDelegateâs methodâââapplication:didFinishLaunchingWithOptions:before returning from it.
Point to be noted: Because the system saves the userâs response, calls to requestAuthorization(options:completionHandler:) method during subsequent launches do not prompt the user again.
Adding Categories and ActionsâââActionable Notifications
The user notifications framework supports adding categories and actions to the notifications.
CategoriesâââDefine the types of notifications that the app supports and communicate to the system how we want a notification to be presented.
ActionsâââEach category can have up to four actions associated with it. Actions are basically custom buttons, that on tap dismisses the notification interface and forwards the selected action to app for immediate handling.
Okayyy..!!! And what does that mean..????đ€ Some code might help you understand that better.
In the above code, we simply created a category named INVITATION with 4 different actionsâââremindLater, accept, decline, comment.
The categories and actions are uniquely identified by their identifiers. Whenever a notification with a category is delivered, the system presents the notification along with all the actions associated with that category once the user expands it. This is what it will look like đ,
Define all the categories and actions just below where you configured notifications in application:didFinishLaunchingWithOptions: method.
Include the category identifier (eg. INVITATION) while scheduling your notification whether locally or remotely. Weâll see how to do that in the next section.
Scheduling Local Notification
Now that weâre done with configuring our notifications, letâs see how to actually schedule one from within the app.
Scheduling a local notification is just 3 simple steps,
- Prepare the content
- Add a triggerâââwhen the notification should be fired
- Schedule it for delivery
Letâs get on with the code quickly, so we donât get confused with everything happening here. LOLÂ đ
In the above code along with the other content, we have also provided a categoryIdentifier to support actionable notifications. In case we donât do that, the system will adopt itâs default behavior.
Thatâs it. Thatâs all needed. And yes it definitely works..hehehe..đ Give it a try before moving any further. You can download the sample from here.
App behaves differently in background and foreground states whenever a notification is delivered.
- App not running / App in Backgroundâââthe system displays local notifications directly to the user. We donât get any callback in the app for that.
- App in Foregroundâââthe system gives app the opportunity to handle the notification internally. The system silences notifications for foreground apps by default.
When app is in foreground while the notification is delivered, we get the callback in UNUserNotificationCenterDelegate's methodâââuserNotificationCenter(_:willPresent:withCompletionHandler:) where you can decide whether to handle the notification silently or alert the user about it.
Donât forget to conform AppDelegate to UNUserNotificationCenterDelegate protocol and setting it as the delegate of UNUserNotificationCenter shared object in application:didFinishLaunchingWithOptions:.
let center = UNUserNotificationCenter.current()
center.delegate = self
Weâre done with local notifications for now. Letâs move on to how we can schedule a notification from outside our app. Before that, letâs have a look on how to respond to the custom actions.
Responding to User Actions
Configuring notifications?? â Scheduling notifications?? â
What about tapping a notification or any custom action in the notification? Where will it lead to?âââin both the cases, system notifies the app of the userâs choice.
Whenever the user performs any action in the notification, the response is sent to UNUserNotificationCenterDelegate's methodâââuserNotificationCenter(_:didReceive:withCompletionHandler:), where we can provide handling specific to each action.
Point to be notedâââif the app is not running when a response is received, the system launches the app in the background to process the response.
Remote Notifications
Push notification or remote notifications, no matter what we call it, itâs one of the most frequestly used one with lots and lots of use-cases.
Be it social media or calendar or any of the utilities app, we could see them almost everywhere. News apps notifying us of the latest content, medium itself alerting us of the latest published articles.
Ever wondered how do they even do that? Local Notifications ???đ€ It could be..it does the same thing..right? May be we can do some more configuration in the local one itself and get that working? But medium for example, donât have access to the app on our personal device, so how could it schedule any notification? Exactly!!! It canât. This is something different and something more just than the local ones.
Send the notification from some point and show it at some other pointâââwill this answer our question? Yupp..surely it will. But how to do that? Remote Notifications it is. This is exactly what it does. This is the feature that has solved THE BIG PROBLEM of âKeeping up-to-dateâ.
Terminology
- APNs âIt is the centerpiece of the remote notifications feature. It is a cloud service that allows approved third-party apps installed on Apple devices to send push notifications from a remote server to users over a secure connection.
- Device TokenâââAn app-specific token that is globally unique and identifies one app-device combination. It enables communication between Provider, APNs and Device.
- ProviderâââServer that actually sends the remote notification including the device token and other information to APNs.
Never cache device tokens in your app; instead, get them from the system when you need them.APNs issues a new device token to your app when certain events happen. The device token is guaranteed to be different, for example, when a user restores a device from a backup, when the user installs your app on a new device, and when the user reinstalls the operating system.When you attempt to fetch a device token but it has not changed, the fetch method returns quickly.
Point to be notedâââThe ability of APNs to deliver remote notifications to a nonrunning app requires the app to have been launched at least once.
How it actually works?
Below is a small and quick explanation of how all the above technologies work together in sync to complete the remote notifications workflow.
- App registers with APNs
- APNs sends device token to Device with then sends it to App
- App sends this device token to Provider
- Provider sends notifications with that device token to APNs which then sends it to Device which then sends it to the App.
If a notification for your app arrives with the device powered on but with the app not running, the system can still display the notification. If the device is powered off when APNs sends a notification, APNs holds on to the notification and tries again later.Handle it in the App
Now that we are aware of what remote notifications are and what all things are needed to make it work, letâs now move on to how we can make our app support it. Obviously, nothing happens on its own đ. We need to make some configurations for the same. To be able to handle remote notifications, our app must:
- Enable remote notifications in capabilitiesâââjust one-click and you are done with this step. In the Capabilities tab of our Xcode project, enable Push Notifications option. Ensure that Push Notifications is added to the App ID that we are using for the project.
2. Register with Apple Push Notification service (APNs) and receive an app-specific device token
Requesting to register with APNs is quick and easy. Just add the below code in UIApplicationDelegateâs methodâ application:didFinishLaunchingWithOptions: before returning from it.
UIApplication.shared.registerForRemoteNotifications()
Now there can be 2 possibilities, either we get registered successfully or the process fails.
On successful registration, APNs sends an app-specific device token to the device inUIApplicationDelegateâs methodâ application:didRegisterForRemoteNotificationsWithDeviceToken:.
In case of faliure, we receive a callback in UIApplicationDelegateâs methodâapplication:didFailToRegisterForRemoteNotificationsWithError:.
3. Send the device token to notification provider server
As of now, weâve received the device token from APNs. Now, we need to send this token to our provider, which will use it while pushing any notifications to our device.
Since we donât have a provider, for now we can use Easy APNs Provider for testing our push notifications. Further in the sections, weâll see how exactly we can make use of this tool.
For now, just download and install it on your mac.
4. Implement support for handling incoming remote notifications
We have got our device token and our provider also knows about it. Next, the Provider will send the notification including this token and other information in it and weâll get it on our device.
Now what? What will happen when it arrives? How will it appear on the device? What will happen when we tap on it? What about all the actions that we configured earlier? Can we get them here?
Too many question âââ..Well, donât worry. Weâll have answers to all of them one-by-one.
- What will happen when it arrivesâââweâll get a callback in UIApplicationDelegateâs methodâ application(_:didReceiveRemoteNotification:fetchCompletionHandler:). It tells the app that a remote notification has arrived that indicates there is data to be fetched.
- How will it appear on the deviceâââit will appear with the default notification interface. If the notificationâs payload is configured with category, it will appear as the actionable notification with all the actions attached to that category. Weâll discuss about the payload in next section.
- What will happen when we tap on itâââsame as local notifications. UNUserNotificationCenterDelegate's methodâââuserNotificationCenter(_:didReceive:withCompletionHandler:) is called with the response object.
Handle it on the Provider
We have covered most of the things we need to integrate push notifications into our app. Although we know how to handle it in the app, we are still short of handling it on the provider.
We have the provider. It knows what device token to use, but that solely wonât pop a notification on our device with some title and other details. Neither will it make any of the actions appear. So, pushing notifications from the provider needs the following items,
- A device token
- APNs certificateâââwe can obtain it from the developer account
- Payloadâââany custom data that you want to send to your app and includes information about how the system should notify the user. Its simply a JSON dictionary with some key value pairs. The below illustration might help you understand it better.
Letâs see whatâs all in that JSON dictionary,
- aps dictionaryâââthe most important one. Contains Apple-defined keys and is used to determine how the system receiving the notification should alert the user.
- alert dictionaryâââit is more of a self-explanatory item. Provides the content of the notification.
- categoryâââfor actionable notifications. All the actions attached to that category will be available in the notifications.
- content-availableâââTo support a background update notification set this key to 1.
- mutable-contentâââTo enable notificationâs modification through Notification Service App Extension, set it to 1.
Here you can read more about customizing the payload as per your requirements. This is a reference to the keys that we can add in aps dictionary
Notification Service App Extension
Uptill now, we know what remote notifications are..how they work..what all we need to get them working..everything..we just got them working perfectly..âïž.
Now question is, what if we want to modify some content in the notification received from provider, before presenting it on the device? What if the notification contains some image link that we need to download before delivering it to the user? Can we do that with what all we already know? We donât have access to the provider..so how will we?
We canât actually. We canât change what we get..but we can definitely change what we present.
Thatâs what Notification Service App Extension is all aboutâ modifying the content of remote notification before delivery. It is as simple as it looks like. No fancy code..nothing..very simple.
Adding Notification Service Extension to the Project
Extensions in an xcode project are added as a target. Select FileâââNewâââTargetâââNotification Service Extension.
Before we begin to modify the content, there are some restrictions on when the content is allowed to be modified. Content can be modified only if:
- The remote notification is configured to display an alert.
- The remote notificationâs aps dictionary includes the mutable-content key with the value set to 1.
We cannot modify silent notifications or those that only play a sound or badge the appâs icon.
Hence, to support any modifications in the notificationsâ content, these conditions must be fulfilled.
Modifying the content
The default notification service extension target provided by Xcode contains a subclass of the UNNotificationServiceExtension class for us to modify.
It contains 2Â methods:
- didReceive(_:withContentHandler:)âââmake any needed changes to the notification and notify the system when youâre done. This method has a limited amount of time (about 30 secs) to perform its task and execute the provided completion block.
- serviceExtensionTimeWillExpire()âââTells us that your extension is about to be terminated. Give us one last chance to submit our changes. If we donât update the notification content before time expires, the system displays the original content.
Letâs look at an example. Weâll change the body in payload in Code Snippetâââ7 to âAddress: Sea Shells Apartments, Mumbaiâ.
All the default implementation of both the methods is provided by the extension itself. We just have to make the changes we want, like in Lineâââ8 in the above code snippet. Just a single line of code for now. Similarly, you can modify other fields as per your requirements.
Notification Content Extension
Having an eye-catching UI is any time better than a default simple UI. Adding some colors..some pretty fonts is never a bad idea. Weâre going to do the same with our notifications, make them look Woww..!!!đ
And and andâŠApple is here to our rescue again. Notification content extension it isâââpresents a custom interface for a delivered local or remote notification.
Adding Notification Content Extension to the Project
I think we already know how to do that. Isnât it? Weâre going to the same what we did for adding Notification Service Extension. Select FileâââNewâââTargetâââNotification Content Extension.
Adding some keys to extensionâs Info.plist
To support custom UI for local & remote notifications, we need to make some changes in the Info.plist file of content extension.
- UNNotificationExtensionCategory (reqd.)âââA string or an array of strings. Each string contains the identifier of a category declared by the app. Category, I must say is really really important for notifications. Custom UI will only appear for the notifications lying in the specified categories.
- UNNotificationExtensionInitialContentSizeRatio (reqd.)âââA floating-point number that represents the initial size of the view controllerâs view expressed as a ratio of its height to its width. Itâs the view controller that weâll use for making custom UI. Weâll discuss that in the upcoming section.
- UNNotificationExtensionDefaultContentHiddenâââtrue: show only custom content, false: show custom+default content.
- UNNotificationExtensionOverridesDefaultTitleâââtrue: set the notificationâs title to the title of the view controller, false: notificationâs title is set to appâs name.
Here is an illustration that can help us understand the above keys better.
In the above illustration, the keys in Info.plist are configured as:
- UNNotificationExtensionCategoryâââINVITATION
- UNNotificationExtensionInitialContentSizeRatioâââ1
- UNNotificationExtensionDefaultContentHiddenâââfalse
- UNNotificationExtensionOverridesDefaultTitleâââfalse
Creating Custom UI
Notification content extension, provide us with a UIViewController that conforms to UNNotificationContentExtension protocol. This controller presents the interface of the notification. The Storyboard file in the extension contains a single ViewController that we can use to create whatever UI we want the notification to present.
Once we create the UI, we need to connect the elements in the NotificationViewController in order to fill in the details. Whenever a notification arrives with an expected category, we receive a callback in UNNotificationContentExtensionâs methodâââdidReceive(_:)Â . This is the place where we can add details to our customised UI.
Weâre almost done with our notificationâs custom UI. Just 1 more thing. Since the custom UI is attached to the notificationsâ category that may have some actions attached to it. And..you got that right..!!! đ€Weâll get our actions automatically without any custom handling. Brilliant..!!!đ
Content + Beautiful UI + Custom ActionsâââEverything done. What more can we ask for. Apple..you are great..!!!đ€©
Last point, we can add handling to the custom actions in the extension too. The system calls didReceive(_:completionHandler:) method to respond to any selected actions. If our view controller doesnât implement that method, the system delivers the selected action to your app for handling.
If implemented, we need to handle all the possible actions in this method. One thing that is important here is the completion closure.
completionThe block to execute when you are finished performing the action. You must call this block at some point during your implementation. The block has no return value
The closure accepts a single parameter dismiss of type UNNotificationContentExtensionResponseOption . We provide the following options:
- doNotDismissâââDonât dismiss the notification interface.
- dismissâââDismiss the notification interface.
- dismissAndForwardAction--Dismiss the notification interface and forward the notification to the app.
That sums up our notifications. Too much to remember? Practise makes Progress đ. Try making your own notifications.
Sample Project
You can download the sample project from here.
Sample project for Notification Content Extension can be found here.
Promotions
Donât forget to read my other articles:
- Everything about Codable in Swift 4
- Color it with GRADIENTSâââiOS
- Coding for iOS 11: How to drag & drop into collections &Â tables
- All you need to know about Today Extensions (Widget) in iOSÂ 10
- UICollectionViewCell selection made easy..!!
Feel free to leave comments in case you have any doubts.
Notifications Inshortsâ All in One was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.