1

I Would like to display the value of the badge number in a label.

So far i've put everything in my viewWillAppear. So every time the controller is loaded the variable is assigned. Here's the code:

var deliveredNotif = Int()

 override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true)
deliveredNotif = UIApplication.shared.applicationIconBadgeNumber
myBadgeLabel.text = "\(deliveredNotif)"
}

My question is: How can i update deliveredNotif if the controller is active and so viewWillAppear is already been called? Meaning if I am in the controller is there a way to trigger a func which will update the value of deliveredNotif every time the value of applicationIconBadgeNumber is changed?

Thank you!

-------UPDATE----MY SOLUTION I created a constant variable: var iconBadgeNumber = NSNumber()

in my Appdelegate i have:

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    completionHandler([.alert, .badge])
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "applicationIconBadgeNumber"), object: nil)
    iconBadgeNumber = UIApplication.shared.applicationIconBadgeNumber + 1 as NSNumber
}

and then in my controller:

override func viewDidLoad() {
    super.viewDidLoad()
 NotificationCenter.default.addObserver(self, selector: #selector(updateIconBadgeNumber), name: NSNotification.Name(rawValue: "applicationIconBadgeNumber"), object: nil)


}

@objc func updateIconBadgeNumber() {
    if iconBadgeNumber == 0 {
        print("zero")
    } else {
    print("there unread notification")
    }
}
Marco
  • 1,051
  • 1
  • 17
  • 40

2 Answers2

2

You can set your UIViewController as an observer for the key path "applicationIconBadgeNumber":

First register for remote notifications. In your didFinishLaunchingWithOptions function, add:

    let center = UNUserNotificationCenter.current()
    center.requestAuthorization(options: [.alert, .badge, .sound]) { _, _ in
        DispatchQueue.main.async {
            application.registerForRemoteNotifications()
        }
    }

don't forget to add also: import UserNotifications on the top of your file

Then add in your viewDidLoad:

UIApplication.shared.addObserver(self, forKeyPath: "applicationIconBadgeNumber", options: .new, context: nil)

Then, override the observeValue function:

    override func observeValue(forKeyPath keyPath: String?,
                                        of object: Any?,
                                           change: [NSKeyValueChangeKey : Any]?,
                                          context: UnsafeMutableRawPointer?) {
        if keyPath == "applicationIconBadgeNumber" {
            deliveredNotif = UIApplication.shared.applicationIconBadgeNumber
            myBadgeLabel.text = "\(deliveredNotif)"
        }
    }
Y.Bonafons
  • 2,329
  • 13
  • 20
  • i've tried to do exactly what you have suggested... but when if the UIViewController is already opened it doesn't trigger the observeValue... – Marco Sep 18 '17 at 16:51
  • I updated my answer: I added the register first. I have tested in a sample project and it works ;) – Y.Bonafons Sep 19 '17 at 09:10
  • Doesn't work on iOS 13 / Swift 5. The callback is triggered only when setting `UIApplication.shared.applicationIconBadgeNumber` manually, but not when a push notification is received – ULazdins Apr 21 '20 at 09:44
1

You have 3 different ways in order to notify an object about a changed value :

  • First of all you have the Notification center in order to notify an observer when your value changed. Check out this post, and more informations on the Internet, you will find what you want.

  • Moreover, you can also use protocol and delegate but it seems kind of heavy for just a notification update on a value.

  • Finally You should definitely look around this post, it explains the principle of the Key-Value Observing (KVO), I am sure you already heard about it.

And to conclude, the ultimate article, will explain you when you should use each of this principle.

KVO vs NSNotification vs protocol/delegates?

You should try to investigate more seriously before posting a question that is already answered multiple times.

Hope this articles will help you.

  • Thx for the answer... i'm new to swift... and i've done some research... unfortunately haven't find my answer... i thought about using Notificationcenter... and it is what i'm trying to do. My issue is that unfortunately to me is not very clear where to put the observer... – Marco Sep 18 '17 at 15:24