Pretty Little Alerts..🥁 Notifications is a way to inform users when new data becomes available for the app, even when the app is not running in the foreground. For example, a messaging app might let the user know when a new message has arrived, and a calendar app might inform the user of an upcoming appointment. With the release of Apple introduces brand new frameworks to support notifications, be it local or remote. is what this release focussed on. iOS-10, Customized notifications Without wasting any time, let’s just quickly jump on to the details. Types of notifications We can broadly classify notifications into 2 categories, — 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. Local notifications use one of your company’s servers to push data to user devices via the Apple Push Notification service(APNs). Remote notifications — 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 , Apple introduced 2 new frameworks to handle notifications, iOS-10 — manages both local and remote notifications. User Notifications Framework — customize the appearance of the system’s notification interface. User Notifications UI Framework We’ll be using these 2 frameworks and some platform-specific APIs to configure our notifications. Along with the frameworks, was also introduced that allows modifying the content of remote notifications before they are delivered. Notification service app extension 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. <a href="https://medium.com/media/8a4c84b1e71564b571dac07c3ac16838/href">https://medium.com/media/8a4c84b1e71564b571dac07c3ac16838/href</a> You need to write that code in AppDelegate’s method — application:didFinishLaunchingWithOptions:before returning from it. Because the system saves the user’s response, calls to method during subsequent launches do not prompt the user again. Point to be noted: requestAuthorization(options:completionHandler:) Adding Categories and Actions — Actionable Notifications The user notifications framework supports adding categories and actions to the notifications. — Define the types of notifications that the app supports and communicate to the system how we want a notification to be presented. Categories — 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. Actions Okayyy..!!! And what does that mean..????🤔 Some code might help you understand that better. <a href="https://medium.com/media/beafb0f3bd1aa031cce11f0fcd8c8be0/href">https://medium.com/media/beafb0f3bd1aa031cce11f0fcd8c8be0/href</a> In the above code, we simply created a category named with 4 different actions — . INVITATION 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. ) while scheduling your notification whether locally or remotely. We’ll see how to do that in the next section. INVITATION 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 😝 <a href="https://medium.com/media/91dd7a6561d4e202f7519e4a7d9d4ef9/href">https://medium.com/media/91dd7a6561d4e202f7519e4a7d9d4ef9/href</a> 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. — the system displays local notifications directly to the user. We don’t get any callback in the app for that. App not running / App in Background — the system gives app the opportunity to handle the notification internally. . App in Foreground The system silences notifications for foreground apps by default When app is in foreground while the notification is delivered, we get the callback in 's method — where you can decide whether to handle the notification silently or alert the user about it. UNUserNotificationCenterDelegate userNotificationCenter(_:willPresent:withCompletionHandler:) <a href="https://medium.com/media/09367e53c539bcf28a80b2db6f28f6a2/href">https://medium.com/media/09367e53c539bcf28a80b2db6f28f6a2/href</a> Don’t forget to conform AppDelegate to UNUserNotificationCenterDelegate protocol and setting it as the delegate of shared object in application:didFinishLaunchingWithOptions:. UNUserNotificationCenter 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 — , where we can provide handling specific to each action. userNotificationCenter(_:didReceive:withCompletionHandler:) <a href="https://medium.com/media/ece91657a4780f66f94ed85aa46447ea/href">https://medium.com/media/ece91657a4780f66f94ed85aa46447ea/href</a> — if the app is not running when a response is received, the system launches the app in the background to process the response. Point to be noted 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? it is. This is exactly what it does. This is the feature that has solved THE BIG PROBLEM of “Keeping up-to-date”. Remote Notifications Terminology **—**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. APNs An app-specific token that is globally unique and identifies one app-device combination. It enables communication between Provider, APNs and Device. Device Token — Server that actually sends the remote notification including the device token and other information to APNs. Provider — 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. — The ability of APNs to deliver remote notifications to a nonrunning app requires the app to have been launched at least once. Point to be noted 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. registers with App A PNs sends device token to with then sends it to APNs Device App sends this device token to App Provider sends notifications with that device token to which then sends it to which then sends it to the . Provider APNs Device 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: — just one-click and you are done with this step. In the tab of our Xcode project, enable option. Ensure that Push Notifications is added to the App ID that we are using for the project. Enable remote notifications in capabilities Capabilities Push Notifications 2. Register with Apple Push Notification service (APNs) and receive an app-specific device token Requesting to register with is quick and easy. Just add the below code in UIApplicationDelegate’s method— application:didFinishLaunchingWithOptions: before returning from it. APNs 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: <a href="https://medium.com/media/fa91b639b7417fa7b0ebc94ae00175bb/href">https://medium.com/media/fa91b639b7417fa7b0ebc94ae00175bb/href</a> 3. Send the device token to notification provider server As of now, we’ve received the device token from Now, we need to send this token to our provider, which will use it while pushing any notifications to our device. APNs. Since we don’t have a provider, for now we can use for testing our push notifications. Further in the sections, we’ll see how exactly we can make use of this tool. Easy APNs Provider 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. — we’ll get a callback in UIApplicationDelegate’s method— . It tells the app that a remote notification has arrived that indicates there is data to be fetched. What will happen when it arrives application(_:didReceiveRemoteNotification:fetchCompletionHandler:) — it will appear with the default notification interface. If the notification’s is configured with it will appear as the actionable notification with all the actions attached to that category. We’ll discuss about the payload in next section. How will it appear on the device payload category, — same as local notifications. UNUserNotificationCenterDelegate's method — is called with the response object. What will happen when we tap on it userNotificationCenter(_:didReceive:withCompletionHandler:) 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 we can obtain it from the developer account APNs certificate — — 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 with some key value pairs. The below illustration might help you understand it better. Payload JSON dictionary <a href="https://medium.com/media/f2fc013833dad4036ae9bc49b78a08f5/href">https://medium.com/media/f2fc013833dad4036ae9bc49b78a08f5/href</a> Let’s see what’s all in that JSON dictionary, — the most important one. Contains and is used to determine how the system receiving the notification should alert the user. aps dictionary Apple-defined keys — it is more of a self-explanatory item. Provides the content of the notification. alert dictionary — for actionable notifications. All the actions attached to that category will be available in the notifications. category To support a background update notification set this key to 1. content-available — — To enable notification’s modification through , set it to 1. mutable-content Notification Service App Extension you can read more about customizing the payload as per your requirements. is a reference to the keys that we can add in aps dictionary Here This Notification Service App Extension Uptill now, we know what are..how they work..what all we need to get them working..everything..we just got them working perfectly..✌️. remote notifications 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 is all about— . It is as simple as it looks like. No fancy code..nothing..very simple. Notification Service App Extension modifying the content of remote notification before delivery Adding Notification Service Extension to the Project Extensions in an xcode project are added as a target. Select — — — File New Target Notification Service Extension. Prerequisites 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 includes the key with the value set to 1. aps dictionary mutable-content 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 class for us to modify. UNNotificationServiceExtension It contains 2 methods: — 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. didReceive(_:withContentHandler:) — 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. serviceExtensionTimeWillExpire() Let’s look at an example. We’ll change the in in to “ ”. body payload Code Snippet — 7 Address: Sea Shells Apartments, Mumbai <a href="https://medium.com/media/e43d7ac3370b49cc2552952a3e2f5530/href">https://medium.com/media/e43d7ac3370b49cc2552952a3e2f5530/href</a> 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… is here to our rescue again. it is — presents a custom interface for a delivered notification. Apple Notification content extension local or remote 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 . Select — — — Notification Service Extension 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 file of content extension. Info.plist A string or an array of strings. Each string contains the identifier of a category declared by the app. , I must say is really really important for notifications. Custom UI will only appear for the notifications lying in the specified categories. UNNotificationExtensionCategory (reqd.) — Category A floating-point number that represents the initial size of the view controller’s view expressed as a . It’s the view controller that we’ll use for making custom UI. We’ll discuss that in the upcoming section. UNNotificationExtensionInitialContentSizeRatio (reqd.) — ratio of its height to its width — : show only custom content, : show custom+default content. UNNotificationExtensionDefaultContentHidden true false : set the notification’s title to the title of the view controller, : notification’s title is set to app’s name. UNNotificationExtensionOverridesDefaultTitle — true false Here is an illustration that can help us understand the above keys better. In the above illustration, the keys in are configured as: Info.plist INVITATION UNNotificationExtensionCategory — 1 UNNotificationExtensionInitialContentSizeRatio — false UNNotificationExtensionDefaultContentHidden — false UNNotificationExtensionOverridesDefaultTitle — Creating Custom UI Notification content extension, provide us with a UIViewController that conforms to 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. UNNotificationContentExtension 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 , we receive a callback in UNNotificationContentExtension’s method — . This is the place where we can add details to our customised UI. category didReceive(_:) <a href="https://medium.com/media/b6a10f6863550817a4c3ac06e1f57f74/href">https://medium.com/media/b6a10f6863550817a4c3ac06e1f57f74/href</a> We’re almost done with our notification’s custom UI. Just 1 more thing. Since the custom UI is attached to the notifications’ that may have some actions attached to it. And..you got that right..!!! 🤘We’ll get our actions automatically without any custom handling. Brilliant..!!!👏 category — Everything done. What more can we ask for. ..you are great..!!!🤩 Content + Beautiful UI + Custom Actions Apple Last point, we can add handling to the custom actions in the extension too. The system calls 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. didReceive(_:completionHandler:) <a href="https://medium.com/media/2a0b65ae058b1c3c4f6f14ada4cf903b/href">https://medium.com/media/2a0b65ae058b1c3c4f6f14ada4cf903b/href</a> If implemented, we need to handle all the possible actions in this method. One thing that is important here is the completion closure. completion The 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 . We provide the following options: UNNotificationContentExtensionResponseOption 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? . Try making your own notifications. Practise makes Progress 🙂 Sample Project You can download the sample project from . here Sample project for can be found . Notification Content Extension 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.