Как добавить различные действия в зависимости от категории, определенной в полезной нагрузке входящего удаленного уведомления? Свифт ОБНОВЛЕНО

Я реализую 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
            ]
        ]

ОБНОВЛЕНИЯ:

  1. Изменены объявления категорий, помещая их в статическую функцию, которую я вызываю didFinishLaunchingWithOptions после проверки разрешения на уведомление и didRegisterForRemoteNotificationsWithDeviceToken после получения токена.
  2. Установите NotificationService's info.plist без каких-либо UNNotificationExtensionCategory, так как я увидел, что это в NotificationContent'ах info.plist.
  3. Пробовал разные настройки 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
        }
    }

Вам необходимо зарегистрироваться для своей категории уведомлений в 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])

Milan 13.06.2019 14:42

Когда ваш push-сервер хочет отправить уведомление пользователю, он может добавить ключ категории с соответствующим значением в полезную нагрузку уведомления. Когда iOS видит push-уведомление с ключом категории, она ищет категории, зарегистрированные приложением. Если iOS находит совпадение, она отображает соответствующие действия с уведомлением.

Hitesh Surani 13.06.2019 14:48

@Milan Я все изменил, как вы, ребята, предложили, смотрите вопрос об обновлениях, но я все еще в той же ситуации, вы видите, что с этим не так?

Vincenzo 13.06.2019 17:43

@iMHiteshSurani Я внес изменения, и теперь все установлено как четыре шага, которые вы перечислили в своем ответе, но ничего не изменилось.

Vincenzo 13.06.2019 17:44
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
2 310
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В документации 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правильно? Большое спасибо.

Vincenzo 13.06.2019 15:54

Наконец-то нашел причину того, что действия не отображаются после всех изменений. В словаре "category": "someValue" нужно объявлять как "click_action":"someValue"... так как это относится к Firebase... не уверен, что я согласен с этим выбором... может быть, это просто для того, чтобы оживить то, что в противном случае было бы скучным существованием разработчиков... спасибо, Firebase. . Помимо сарказма, большое спасибо за помощь и в этом.

Это связано с тем, что полезная нагрузка Firebase используется для создания уведомлений для всех поддерживаемых платформ, а «категория» — это ключ, специфичный для Apple. Чтобы настроить сообщения Firebase для Apple, вам необходимо включить следующее: "apns": { "payload": { "category": "someValue" } } Объект полезной нагрузки — это полезная нагрузка Apple, в которую вы помещаете «aps», «category» и другие вещи. В противном случае вы используете «click_action» на верхнем уровне, чтобы Firebase правильно переводил его в соответствующий ключ на всех платформах («click_action» на самом деле является версией «категории» для Android)

Arkadii 25.02.2021 13:39

Другие вопросы по теме