Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Appboy iOS 10 Rich Notifications Service Extension written in Swift
//
// NotificationService.swift
//
// Created by Luka Gabric on 12/04/2017.
// Copyright © 2017 Luka Gabric. All rights reserved.
//
import UserNotifications
import NotificationServiceExtensionCommon
fileprivate let AppboyAPNSDictionaryKey = "ab"
fileprivate let AppboyAPNSDictionaryAttachmentKey = "att"
fileprivate let AppboyAPNSDictionaryAttachmentURLKey = "url"
fileprivate let AppboyAPNSDictionaryAttachmentTypeKey = "type"
public class AppboyNotificationService: UNNotificationServiceExtension {
//MARK: - Vars
private var contentHandler: ((UNNotificationContent) -> Void)?
private var originalContent: UNNotificationContent?
private let session: URLSession
private let fileManager: FileManager
//MARK: - Init
public init() {
self.session = URLSession(configuration: URLSessionConfiguration.default)
self.fileManager = FileManager.default
}
//MARK: - Public
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
self.originalContent = request.content
guard
let content = self.originalContent?.mutableCopy() as? UNMutableNotificationContent,
let appboyPayload = request.content.userInfo[AppboyAPNSDictionaryKey] as? [AnyHashable : Any],
let attachmentPayload = appboyPayload[AppboyAPNSDictionaryAttachmentKey] as? [AnyHashable : Any],
let attachmentURLString = attachmentPayload[AppboyAPNSDictionaryAttachmentURLKey] as? String,
let attachmentURL = URL(string: attachmentURLString),
let attachmentType = attachmentPayload[AppboyAPNSDictionaryAttachmentTypeKey] as? String else {
self.displayOriginalContent()
return
}
self.session.downloadTask(with: attachmentURL, completionHandler: { temporaryFileLocation, response, error in
guard let temporaryFileLocation = temporaryFileLocation, error == nil else {
self.displayOriginalContent()
return
}
let fileSuffix = ".\(attachmentType)"
let path = temporaryFileLocation.path + fileSuffix
let typedAttachmentURL = URL(fileURLWithPath: path)
do {
try self.fileManager.moveItem(at: temporaryFileLocation, to: typedAttachmentURL)
} catch {
self.displayOriginalContent()
return
}
guard let attachment = try? UNNotificationAttachment(identifier: "", url: typedAttachmentURL, options: nil) else {
self.displayOriginalContent()
return
}
content.attachments = [attachment]
self.display(content: content)
}).resume()
}
override func serviceExtensionTimeWillExpire() {
self.displayOriginalContent()
}
//MARK: - Private
private func display(content: UNNotificationContent) {
if let contentHandler = self.contentHandler {
contentHandler(content)
}
}
private func displayOriginalContent() {
if let originalContent = self.originalContent {
self.display(content: originalContent)
}
}
//MARK: -
}
Owner

lukagabric commented Jul 15, 2017

For more info check my blog post.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment