问题
I'm implementing push notifications in my two related apps and so far I'm able to send a notifications, device to device, and to a topic. On receiving it, notification displays the image at url sent with the payload. My goal is to add actions to the topic notifications, and they would be different for each topic. Ej. actions for "shop-promotions"
topic notifications (namely "buy"
) would be different from "news" topic notification ( namely "play"
). So I thought to send a "category" parameter in the remote notification's payload and use that to differentiate between different incoming notifications and display the correct set of actions. Is it possible to define actions in NotificationExtension.swift didReceive
or is mandatory to also use a custom UI to display actions?
In https://www.pluralsight.com/guides/creating-ios-rich-push-notifications is shown as possible but I'm not succeeding at it.
I'm declaring them as :
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
print("NotificationService: dide receive called")
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
if let urlString = bestAttemptContent.userInfo["attachment-url"] as? String,
let data = NSData(contentsOf: URL(string:urlString)!) as Data? {
let path = NSTemporaryDirectory() + "attachment"
_ = FileManager.default.createFile(atPath: path, contents: data, attributes: nil)
do {
let file = URL(fileURLWithPath: path)
let attachment = try UNNotificationAttachment(identifier: "attachment", url: file,options:[UNNotificationAttachmentOptionsTypeHintKey : "public.jpeg"])
bestAttemptContent.attachments = [attachment]
} catch {
print(error)
}
// Actions
if let category = bestAttemptContent.userInfo["category"] as? String {
if category == "shop-promotions" {
let buy = UNNotificationAction(identifier: "buy", title: "Buy", options: [])
let close = UNNotificationAction(identifier: "close", title: "Close", options: [])
let category = UNNotificationCategory(identifier: "shop-promotions", actions: [buy,close], intentIdentifiers: ["buy","close"], options: [])
UNUserNotificationCenter.current().setNotificationCategories([category])
}
}
} // else {
// if let contentHandler: ((UNNotificationContent) -> Void) =
// self.notificationContentHandler,
// let content: UNNotificationContent = self.notificationContent {
// contentHandler(content) }
let buy = UNNotificationAction(identifier: "buy", title: "Buy", options: [])
let close = UNNotificationAction(identifier: "close", title: "Close", options: [])
let category = UNNotificationCategory(identifier: "shop-promotions", actions: [buy,close], intentIdentifiers: [], options: [])
UNUserNotificationCenter.current().setNotificationCategories([category])
contentHandler(bestAttemptContent)
}
and this is the dictionary sent for the notification:
let postParams: [String : Any] = [
"to": topic,
"notification": [
// "badge" : 1, sendig the badge number, will cause aglitch
"body": body,
"title": title,
"subtitle": subtitle,
"text": "some text",
"sound" : true, // or specify audio name to play
"priority": "high",
"content_available": true,
"mutable_content": true,
"category": "shop-promotions"
],
"data" : [
"attachment-url": dataUrl,
// "media_type":"image",
"productId": productId,
"price": price
]
]
UPDATES:
- Changed the categories declarations putting them in a static function that I call in
didFinishLaunchingWithOptions
after checking for notification permission anddidRegisterForRemoteNotificationsWithDeviceToken
after getting the token. - Set
NotificationService
'sinfo.plist
without anyUNNotificationExtensionCategory
as I saw that that's inNotificationContent
'sinfo.plist
. - Tried different
Target Membership
settings for bothNotificationService.swift
andinfo.plist
. What's the right configuration?
Still in the same situation of only the image showing with the notification.
Can you see what's missing to set up correctly?
The actions function is this:
static func configurePushCategories() {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.badge,.sound]) { (granted:Bool, error:Error?) in
if error != nil {
print(error?.localizedDescription as Any)
}
if granted {
print("Permission granted")
} else {
print("Permission not granted")
}
}
// actions
let buy = UNNotificationAction(identifier: "buy", title: "Buy", options: [.foreground])
let play = UNNotificationAction(identifier: "play", title: "Play", options: [.foreground])
let close = UNNotificationAction(identifier: "close", title: "Close", options: [.foreground])
// let shopPromotionsCategory = UNNotificationCategory(identifier: "shop-promotions", actions: [buy,close], intentIdentifiers: ["buy","close"], options: [])
// let fixItPromotionsCategory = UNNotificationCategory(identifier: "fix-it-promotions", actions: [buy,close], intentIdentifiers: ["buy","close"], options: [])
// let cityFixItNewsCategory = UNNotificationCategory(identifier: "city-fix-it-news", actions: [play,close], intentIdentifiers: ["play","close"], options: [])
// let countryFixItNewsCategory = UNNotificationCategory(identifier: "country-fix-it-news", actions: [play,close], intentIdentifiers: ["play","close"], options: [])
let shopPromotionsCategory = UNNotificationCategory(identifier: "shop-promotions", actions: [buy,close], intentIdentifiers: [], options: [])
let fixItPromotionsCategory = UNNotificationCategory(identifier: "fix-it-promotions", actions: [buy,close], intentIdentifiers: [], options: [])
let cityFixItNewsCategory = UNNotificationCategory(identifier: "city-fix-it-news", actions: [play,close], intentIdentifiers: [], options: [])
let countryFixItNewsCategory = UNNotificationCategory(identifier: "country-fix-it-news", actions: [play,close], intentIdentifiers: [], options: [])
UNUserNotificationCenter.current().setNotificationCategories([shopPromotionsCategory,fixItPromotionsCategory, cityFixItNewsCategory, countryFixItNewsCategory])
} else {
// Fallback on earlier versions
}
}
回答1:
Apple documentation states:
When your push server wants to send a notification to a user, it can add a category key with an appropriate value to the notification’s payload. When iOS sees a push notification with a category key, it looks up the categories that were registered by the app. If iOS finds a match, it displays the corresponding actions with the notification.
#Notification Payload:
{
"aps": {
"category": "MEETING_INVITATION",
"alert": {
"title": "Weekly Staff Meeting",
"body": "Every Tuesday at 2 pm"
}
},
"MEETING_ID": "123456789",
"USER_ID": "ABCD1234"
}
To support actionable notifications, you must:
Declare one or more notification categories at launch time from your iOS app.
Assign appropriate actions to your notification categories.
Handle all actions that you register.
Assign category identifiers to notification payloads when generating notifications.
回答2:
Finally found the reason for actions not showing after all the changes. In the dictionary "category": "someValue"
needs to be declared as "click_action":"someValue"
..as it goes to Firebase.. not sure I agree with that choice..maybe it's just to spice up what would have been an otherwise boring existence as developers..thank you Firebase..
Sarcasm apart thank you very much for the help on this one too.
来源:https://stackoverflow.com/questions/56579999/how-to-add-different-actions-depending-on-the-category-defined-in-incoming-remot