Closed ghost closed 7 years ago
Hi @mosn
Can you give us some more information about your use cases? e.g. if you're using Swift for your notification extension, are you doing something beyond our default handling? And regarding better documentation for Notification Extensions - are there particular pieces of information you would find high value to have more detail on?
We'll be updating our iOS 10 notification documentation in the near future and also refining that integration point, so any information you can provide to help us best do so would be much appreciated.
Thanks very much for the feedback, Brian
@briancaw Thanks for the quick response,
I'm trying to setup enahcne iOS10 notification (Notification Extensions) in swift and the documentation points out to see the sample code implenetation but that's written in Objective-C. Would be great to see that sample in swift too.
Also I think in general the documentation can improve a bit, an example would be SETP4:1 which uses UNUserNotificationCenter
without pointing out to the reader that USERNOTIFICATION
needs to be imported first.
or STEP4:3 which asks the user to implement delegate method didReceive response: UNNotificationResponse
without mentioning the need to conform to UNUserNotificationCenterDelegate
protocol beforehand
not to mention some of the code results in basic compiler warnings i.e STEP4:1 where immutable variable setting
is declar with var
Thanks very much for that feedback @mosn. We'll circle back and figure out best next steps here - I suspect we'll be able to get you some sample code in the not too distant future, though we'll have to solidify our next steps and timeline before committing to anything.
If you have any information regarding urgency on your end it'd be useful for us to consider in our planning.
Thanks, Brian
@briancaw unless you can provide the sample in next 48 hours, it has no use for me. I will see if I can convert the objc to swift and get it going.
Hey @mosn,
I converted the Object-C sample code to Swift. Do you mind giving it a try?
import UserNotifications
import UIKit
let AppboyAPNSDictionaryKey = "ab"
let AppboyAPNSDictionaryAttachmentKey = "att"
let AppboyAPNSDictionaryAttachmentURLKey = "url"
let AppboyAPNSDictionaryAttachmentTypeKey = "type"
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
var originalContent: UNMutableNotificationContent?
var abortOnAttachmentFailure: Bool = false
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
self.bestAttemptContent = (request.content.mutableCopy() as! UNMutableNotificationContent)
self.originalContent = (request.content.mutableCopy() as! UNMutableNotificationContent)
print("[APPBOY] Push with mutable content received.")
var attachments : [UNNotificationAttachment] = []
let userInfo: [AnyHashable : Any]! = request.content.userInfo
// Check that the push is from Appboy
if (userInfo![AppboyAPNSDictionaryKey] as Any? == nil) {
// Note: if you have other push senders and want to handler here, fork your code here to handle
self.displayOriginalContent("Push is not from Appboy.")
return
}
let appboyPayload: [AnyHashable : Any]! = userInfo![AppboyAPNSDictionaryKey] as! [AnyHashable : Any]!
// Check that the push has an attachment
if (appboyPayload[AppboyAPNSDictionaryAttachmentKey] as Any? == nil) {
self.displayOriginalContent("Push has no attachment.")
return
}
let attachmentPayload: [AnyHashable : Any]! = appboyPayload[AppboyAPNSDictionaryAttachmentKey] as! [AnyHashable : Any]!
// Check that the attachment has a URL
if (attachmentPayload[AppboyAPNSDictionaryAttachmentURLKey] == nil ) {
self.displayOriginalContent("Push attachment has no url.")
return
}
let attachmentURLString: String! = attachmentPayload[AppboyAPNSDictionaryAttachmentURLKey] as! String
print("[APPBOY] Attachment URL string is \(attachmentURLString)")
// Get the type
if(attachmentPayload[AppboyAPNSDictionaryAttachmentTypeKey] == nil) {
self.displayOriginalContent("Push attachment has no type.")
return
}
let attachmentType: String = attachmentPayload[AppboyAPNSDictionaryAttachmentTypeKey] as! String
print("[APPBOY] Attachment type is \(attachmentType)")
let fileSuffix: String = ".\(attachmentType)"
// Download, store, and attach the content to the notification
if (attachmentURLString != nil) {
guard let attachmentURL = URL.init(string: attachmentURLString) else {
self.displayOriginalContent("Cannot parse \(attachmentURLString) to URL.")
return
}
let session = URLSession(configuration:URLSessionConfiguration.default)
session.downloadTask(with: attachmentURL,
completionHandler: { (temporaryFileLocation, response, error) in
if (error != nil || temporaryFileLocation == nil) {
self.displayOriginalContent("Error fetching attachment, displaying content unaltered: \(error?.localizedDescription)")
return
} else {
print("[Appboy] Data fetched from server, processing with temporary file url \(temporaryFileLocation!.absoluteString)")
let fileManager = FileManager.default
let typedAttachmentURL = URL(fileURLWithPath:"\(temporaryFileLocation!.path)\(fileSuffix)")
do {
try fileManager.moveItem(at: temporaryFileLocation!, to: typedAttachmentURL)
} catch {
self.displayOriginalContent("Failed to move file path.")
return
}
let attachment: UNNotificationAttachment? = try? UNNotificationAttachment.init(identifier: "",
url: typedAttachmentURL,
options: nil)
if (attachment == nil) {
self.displayOriginalContent("Attachment returned error.")
return
}
attachments = [attachment!]
self.bestAttemptContent!.attachments = attachments;
self.contentHandler!(self.bestAttemptContent!);
}
}).resume()
}
}
func displayOriginalContent(_ extraLogging: String) {
print("[APPBOY] \(extraLogging)")
print("[APPBOY] Displaying original content.")
self.contentHandler!(self.originalContent!)
}
override func serviceExtensionTimeWillExpire() {
// 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.
self.displayOriginalContent("Service extension called, displaying original content.")
}
}
Thanks, Wenzhi
change line: (attachments array is empty by default, you can't replace value by index 0)
attachments[0] = attachment!
on
attachments = [attachment!]
Thanks, @shuhrat10! I updated the comment.
Please update the sample code to include examples for swift iOS 10+ Notification or Provide better documentation for Notification Extensions