Search code examples
iospush-notificationapple-push-notificationsunusernotificationcenternotification-action

Adding Dynamic Actions to UNNotificationCategory


I am currently facing an issue where I need to be able to change the actions of a UNNotificationCategory based on information sent with the notification. Currently my categories are set up similarly to this:

func registerNotificationSettings(){
    let acceptAction = UNNotificationAction(identifier: "accept", title:  "accept", options: [])
    let denyAction = UNNotificationAction(identifier: "deny", title: "deny", options: [])

    let acceptCategory = UNNotificationCategory(identifier: "2", actions: [acceptAction], intentIdentifiers: [], options: [])
    let denyCategory = UNNotificationCategory(identifier: "1", actions: [denyAction], intentIdentifiers: [], options: [])

    let center = UNUserNotificationCenter.current()
    center.setNotificationCategories([acceptCategory, denyCategory])

    center.requestAuthorization(options: [.alert, .badge, .sound]){
       (granted, error) in
        if (granted){
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    }
}

This configuration is working, however, I need the ability to change the default action for each category based on user settings. For example, in the "denyAction" "deny" may need to be change to "reject", or in the "acceptAction" "accept" may need to be changed to "confirm". These are settings that we have made variable for the user to specify themselves within the application, and I have no way of knowing what they may change it to.

Currently we have the notifications sending "response" dictionaries in the userInfo of each notification, but I don't know how it is possible to change notification actions at the time of receiving the notification. The only documentation I have found sets these actions ahead of time. Does anyone know if this is possible?


Solution

  • I was able to solve this issue by creating a method requesting a list of possible states from my server which includes the actions associated with that state. Then I create a UNNotificationCategory for each state and a UNNotificationAction for each action. I call this method every time the application runs. This is not a perfect solution because if someone never force quits the app, and the state data changes, then I don't get the new data.

    Here is some of my code

    for state in notificationStates {
    
                var notificationActions : [UNNotificationAction] = []
                for action in state.actions {
                    let notificationAction = UNNotificationAction(identifier: action, title: action, options: [])
                    notificationActions.append(notificationAction)
                }
    
                let muteAction = UNNotificationAction(identifier: "mute", title: "Mute", options: [])
                let commentAction = UNTextInputNotificationAction(identifier: "inline-comment", title: "Add Comment", options: [], textInputButtonTitle: "Add Comment", textInputPlaceholder: "Comment")
    
                notificationActions.append(muteAction)
                notificationActions.append(commentAction)
    
                let notificationCategory = UNNotificationCategory(identifier: state.id, actions: notificationActions, intentIdentifiers: [], options: [])
                notificationCategories.insert(notificationCategory)
            }
            center.setNotificationCategories(notificationCategories)