King
King

Reputation: 2025

Incrementing badge value based on number of notification

I am displaying notifications in my application and I am having difficulties incrementing the badge number based on the number of notifications. My code is specified below:

func notifcation(model: Model) -> Void {
    let calendar = Calendar.current
    guard let date = model.remiderDate else {return}
    let title = model.name
    let body = model.desc
    let comp2 = calendar.dateComponents([.year,.month,.day,.hour,.minute], from: date)
    let trigger = UNCalendarNotificationTrigger(dateMatching: comp2, repeats: true)
    let content = UNMutableNotificationContent()
    content.title = title
    content.body = body
    content.sound = UNNotificationSound.default()
    content.badge = UIApplication.shared.applicationIconBadgeNumber + 1 as NSNumber

    let identifier = "\(date)"
    let request = UNNotificationRequest(identifier: identifier,
                                        content: content, trigger: trigger)


    center.add(request, withCompletionHandler: { (error) in
        if let error = error {
            // Something went wrong
            print(error as Any)
        }
    })
}

I am able to get multiple notifications but I am unable to increment the badge value to reflect the number of notifications.

The application notification also does not show up if the application is currently running but notifications work if the application is in the background.

Upvotes: 0

Views: 1288

Answers (3)

landnbloc
landnbloc

Reputation: 1068

For anyone using firebase this should be helpful. Most the examples I looked at had deprecated payload structures. Looks like you have to keep track of the badge value in your database. In my case, the best place to increment that value was while sending a notification. Just set it back to 0 when app becomes active in your App Delegate

//Call from firestore trigger

 var sendPayload = function(id, title, body){
    
            return admin.firestore().doc('users/' + id).get().then(userDoc =>{
                             
                if (!userDoc.exists){
                    return null
                }
                var newBadge = incrementString(userDoc.get('badge'))
                const token = userDoc.get('token')
    
                if (token === null || typeof token === 'undefined'){
                    return null
                }
    
                admin.firestore().doc('users/' + id).set({
                     badge : newBadge
                         }, {merge: true});
    
    
                console.log(token)
                const payload = {
                    notification : {
                        title : title,
                        body : body,
                        sound: 'default',
                        badge: newBadge
                    },    
                }
                   return admin.messaging().sendToDevice(token,payload);
              })
        }

//App Delegate Client

    func application(_ application: UIApplication,
    didReceiveRemoteNotification userInfo: [AnyHashable : Any],
    fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void){
        

        func setBadge(){
            if let newBadge = Int(info.badge){
                UIApplication.shared.applicationIconBadgeNumber = newBadge
            }
        }

        switch  application.applicationState {
          case .inactive:
                setBadge()
          case .background:
              // update badge count here
               setBadge()
          case .active:
            break
        @unknown default:
            fatalError("unknown state _app delegate")
        }
}

 func applicationDidBecomeActive(_ application: UIApplication) {

        if  UIApplication.shared.applicationIconBadgeNumber != 0{
            UIApplication.shared.applicationIconBadgeNumber = 0
            if let userID = Auth.auth().currentUser?.uid{
                let dict = ["badge" : "0"]
                AccountOperations.updateDocument(rootCollection: "users", doc: userID, newValueDict: dict)
            }
           
            
        }
}

Upvotes: 0

D.3
D.3

Reputation: 145

Actually this line content.badge = UIApplication.shared.applicationIconBadgeNumber + 1 as NSNumber is missleading. Serverside has it's own key for the app badge number. In case you want a full control on the badge coun, related to your user actions, you have to implement some logic on the UIApplicationDelegate to reflect the desired behaviour. Something like a cache of numbers vs actions polling and logic to work with that cache. Call it when your application will enter foreground to sanitize the badge. If your APNS server side sends you the static badge count - talk to them. As far as I know, there is no way to correct a wrong badge count from a server if your application is not running and the callbacks are not called

EDIT: probably I've confused push and local notifications in the question. Will leave the answer as a reminder for me, to read the question twice (at least) :)

Upvotes: 0

ielyamani
ielyamani

Reputation: 18591

You can increment the badge using this :

UIApplication.shared.applicationIconBadgeNumber += 1

Or :

content.badge = NSNumber(integerLiteral: UIApplication.shared.applicationIconBadgeNumber + 1)

To receive notifications whilst the app is in the foreground, your view controller should conform to the UNUserNotificationCenterDelegate protocol and implement the userNotification:willPresent method, and then declare your view controller as the notification delegate in viewDidLoad():

class ViewController: UIViewController, UNUserNotificationCenterDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        //...
        UNUserNotificationCenter.current().delegate = self
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert, .sound])
    }
}

For more on local notifations, have a look here.

Upvotes: 2

Related Questions