Я реализую push-уведомления в двух своих связанных приложениях, и до сих пор я могу отправлять уведомления с устройства на устройство и в тему. При получении уведомление отображает изображение по URL-адресу, отправленному с полезной нагрузкой. Моя цель — добавить действия в уведомления темы, и они будут разными для каждой темы. Эй. действия для уведомлений темы "shop-promotions"
(а именно "buy"
) будут отличаться от уведомления темы «новости» (а именно "play"
). Поэтому я решил отправить параметр «категория» в полезной нагрузке удаленного уведомления и использовать его, чтобы различать разные входящие уведомления и отображать правильный набор действий. Можно ли определить действия в NotificationExtension.swift didReceive
или обязательно использовать настраиваемый пользовательский интерфейс для отображения действий?
В https://www.pluralsight.com/guides/creating-ios-rich-push-уведомления показано как возможное, но мне это не удается.
Я объявляю их как:
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)
}
и это словарь, отправленный для уведомления:
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
]
]
ОБНОВЛЕНИЯ:
didFinishLaunchingWithOptions
после проверки разрешения на уведомление и didRegisterForRemoteNotificationsWithDeviceToken
после получения токена.NotificationService
's info.plist
без каких-либо UNNotificationExtensionCategory
, так как я увидел, что это в NotificationContent
'ах info.plist
.Target Membership
для NotificationService.swift
и info.plist
. Какая правильная конфигурация?Все еще в той же ситуации, когда отображается только изображение с уведомлением.
Вы видите, чего не хватает для правильной настройки?
Функция действий такова:
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
}
}
Когда ваш push-сервер хочет отправить уведомление пользователю, он может добавить ключ категории с соответствующим значением в полезную нагрузку уведомления. Когда iOS видит push-уведомление с ключом категории, она ищет категории, зарегистрированные приложением. Если iOS находит совпадение, она отображает соответствующие действия с уведомлением.
@Milan Я все изменил, как вы, ребята, предложили, смотрите вопрос об обновлениях, но я все еще в той же ситуации, вы видите, что с этим не так?
@iMHiteshSurani Я внес изменения, и теперь все установлено как четыре шага, которые вы перечислили в своем ответе, но ничего не изменилось.
В документации Apple говорится:
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.
#Полезная нагрузка уведомления:
{
"aps": {
"category": "MEETING_INVITATION",
"alert": {
"title": "Weekly Staff Meeting",
"body": "Every Tuesday at 2 pm"
}
},
"MEETING_ID": "123456789",
"USER_ID": "ABCD1234"
}
Для поддержки действенных уведомлений необходимо:
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.
О, понятно.. Я отклонился от этого, увидев, что если вы используете пользовательский интерфейс с расширением содержимого уведомлений, вам нужно будет объявить ответы в didReceive(_ responsein NotificationViewController, поэтому я подумал, что действия должны быть объявлены в NotificationService.swift как учебник, которому я следовал, объявлял их там, уводя меня в неправильном направлении.. Так что я могу избежать настройки словаря категорий в info.plist
правильно? Большое спасибо.
Наконец-то нашел причину того, что действия не отображаются после всех изменений. В словаре "category": "someValue"
нужно объявлять как "click_action":"someValue"
... так как это относится к Firebase... не уверен, что я согласен с этим выбором... может быть, это просто для того, чтобы оживить то, что в противном случае было бы скучным существованием разработчиков... спасибо, Firebase. .
Помимо сарказма, большое спасибо за помощь и в этом.
Это связано с тем, что полезная нагрузка Firebase используется для создания уведомлений для всех поддерживаемых платформ, а «категория» — это ключ, специфичный для Apple. Чтобы настроить сообщения Firebase для Apple, вам необходимо включить следующее: "apns": { "payload": { "category": "someValue" } }
Объект полезной нагрузки — это полезная нагрузка Apple, в которую вы помещаете «aps», «category» и другие вещи. В противном случае вы используете «click_action» на верхнем уровне, чтобы Firebase правильно переводил его в соответствующий ключ на всех платформах («click_action» на самом деле является версией «категории» для Android)
Вам необходимо зарегистрироваться для своей категории уведомлений в didFinishLaunchingWithOptions в AppDelegate для вашей категории. Переместите свой код в didFinishLaunchingWithOptions
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])