Click To Download Full Source Code
- iOS: 10
- Language: Swift
- Xcode Version: 8
- Mac OS: 10.12
Step 1: Create Simple Xcode Project
For this demo, first create a Xcode project by selecting ‘Single View Application’ type.
Step 3: Registering your applications for remote notifications
- Now open AppDelegate.swift. For that open this screen first
- Import ‘UserNotifications’ and write below code in ‘didFinishLaunchingWithOptions’ method
let center = UNUserNotificationCenter.current() center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in // actions based on whether notifications were authorised or not guard error == nil else { //Display Error.. Handle Error.. etc.. return } if granted { //Do stuff here.. } else { //Handle user denying permissions.. } } application.registerForRemoteNotifications()
- Now you are done with registering remote notifications.
Step 4: Add Notification Service Extension
- Now we need to add ‘Notification Service Extension’ in application. For that open this screen first
- Select ‘Notification Service Extension’ in your application and click on ‘Next’ button
- Enter name of the extension. Here we have entered ‘Service Extension’. Then click on ‘Finish’ button.
- Once you click on ‘Finish’ button, user will be able to see below screen.
- In this screen, Xcode is asking you to active scheme for this new extension. So you can use this scheme for building and debugging. Schemes can be chosen in the toolbar or Product menu. Please activate scheme for ‘Service Extension’.
- Now you are done with adding notification service extension.
Step 5: Understanding what files you are getting after adding Notification Service Extension
In this extension, you will be able to find that there are total two files:
- Info.plist
- NotificationService.swift
Info.plist:
- In plist file you have to mention what type of operation you want to perform by using Notification Service Extension.
NotificationService.swift
In swift file you have to implement all operations which you like to handle as per supported type for Notification Service Extension.
- You will see a couple of delegate method – one for receiving a notification request and one for handling the expiration of the service extension.
- Now focussing on this ‘didReceiveRequestWithContentHandler’ method.
- Write below code in ‘didReceiveRequestWithContentHandler’ method.
if let bestAttemptContent = bestAttemptContent { // Modify the notification content here... // Get the custom data from the notification payload if let notificationData = bestAttemptContent.userInfo["data"] as? [String: String] { // Grab the attachment if let urlString = notificationData["attachment-url"], let fileUrl = URL(string: urlString) { // Download the attachment URLSession.shared.downloadTask(with: fileUrl) { (location, response, error) in if let location = location { // Move temporary file to remove .tmp extension let tmpDirectory = NSTemporaryDirectory() let tmpFile = "file:".appending(tmpDirectory).appending(fileUrl.lastPathComponent) let tmpUrl = URL(string: tmpFile)! try! FileManager.default.moveItem(at: location, to: tmpUrl) // Add the attachment to the notification content if let attachment = try? UNNotificationAttachment(identifier: "", url: tmpUrl) { self.bestAttemptContent?.attachments = [attachment] } } // Serve the notification content self.contentHandler!(self.bestAttemptContent!) }.resume() } } }
- It may seem like a lot is happening here, but it’s really straightforward. Initially we are exploring the notification’s payload for the dictionary named ‘data’ that contains the key ‘attachment-url’. If this key exists, we download the media at the URL specified in the key’s value.
- The URLSession downloads the media to temporary storage and appends a .tmp file extension which we need to remove so that the application can infer the file type and display it. So to do this, we need to move the file to the application’s local File Manager and that’s it – our media is ready to be attached to the notification content, and served to the user.
- Now focussing on this ‘serviceExtensionTimeWillExpire’ method.
- This Called just before the extension will be terminated by the system
- Use this as an opportunity to deliver your ‘best attempt’ at modified content; otherwise the original push payload will be used.
- Now you are done with notification service rich notification.
Step 6: Registering device token for remote notifications
- Now open AppDelegate.swift. For that open this screen first
- Create Data extension for getting the data to hexString.
extension Data { func hexString() -> String { return self.reduce("") { string, byte in string + String(format: "%02X", byte) } } }
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let deviceTokenString = deviceToken.hexString() print("deviceToken :\(deviceTokenString)") }
- Use device token for sending push notification.
Step 8: How to test
- We mentioned that only certain notifications were intercepted by the Service Extension. So, how does iOS know which notifications to intercept? Well, you just add a mutable-content tag to your payload and set it to 1.
- The final thing you need to do is to add the media attachment URL to the payload in its own dictionary that we’ve named ‘data’, but you can name it anything. Simply add a key-value pair to the dictionary and as long as the key you’ve used in your Service Extension is the same as the key here, you’re done!
- The following is a Payload example,
{ "aps": { "alert": { "title": "Pokemon Go", "subtitle": "iOS 10 support!", "body": "Now add more content to your Push Notifications!" }, "mutable-content": 1 }, "data": { "attachment-url": "https://psprovocative.com/wp-content/uploads/2016/08/pokemon-go-heart-pokestopjpg-d1c6dba768e27a23-300x300.jpg" } }
You can now send images, videos, audio, and GIFs in your iOS 10 Push Notifications! Simply change the URL to point to another media file and see the results for yourself.