title: How to add different actions depending on the category defined in incoming remote notification payload? Swift UPDATED
body: <p>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 <code>"shop-promotions"</code> topic notifications (namely  <code>"buy"</code>) would be different from "news" topic notification ( namely <code>"play"</code>). 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 <code>didReceive</code> or is mandatory to also use a custom UI to display actions? 
  In <a href="https://www.pluralsight.com/guides/creating-ios-rich-push-notifications" rel="nofollow noreferrer">https://www.pluralsight.com/guides/creating-ios-rich-push-notifications</a> is shown as possible but I'm not succeeding at it.</p>
  
  <p>I'm declaring them as :</p>
  
  <pre><code>override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -&gt; 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) -&gt; 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)
          }
  </code></pre>
  
  <p>and this is the dictionary sent for the notification:</p>
  
  <pre><code>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
              ]
          ]
  </code></pre>
  
  <p>UPDATES:</p>
  
  <ol>
  <li>Changed the categories declarations putting them in a static function that I call in <code>didFinishLaunchingWithOptions</code>after checking for notification permission and <code>didRegisterForRemoteNotificationsWithDeviceToken</code>after getting the token.</li>
  <li>Set <code>NotificationService</code>'s <code>info.plist</code> without any <code>UNNotificationExtensionCategory</code>as I saw that that's in <code>NotificationContent</code>'s <code>info.plist</code>.</li>
  <li>Tried different <code>Target Membership</code> settings for both <code>NotificationService.swift</code> and <code>info.plist</code>. What's the right configuration?</li>
  </ol>
  
  <p>Still in the same situation of only the image showing with the notification.</p>
  
  <p>Can you see what's missing to set up correctly?</p>
  
  <p>The actions function is this:</p>
  
  <pre><code>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
          }
      }
  </code></pre>