Why I can't receive a notification on an observer class inside a View struct in SwiftUI?

Viewed 317

I have the following code, where I create a class that acts as an observer of a default notification. But the notification never arrives:

struct NotificationCenterExampleView: View {
    
    let observerA = ObserverClassA()
    
    init() {
        print("NotificationCenterExampleView init")
        
        
        NotificationCenter.default.addObserver(observerA, selector: #selector(ObserverClassA.receivedNotification(notification:)), name: Notification.Name("CustomNotification"), object: "This is the message")
        let notificationToPost = Notification(name: Notification.Name("CustomNotification"), object: "Message being sent", userInfo: nil)
        NotificationCenter.default.post(notificationToPost)
    }
    
    var body: some View {
        Text("Notification Center Example")
            .frame(minWidth: 250, maxWidth: 500, minHeight: 250, maxHeight: 500)
    }
}

class ObserverClassA: NSObject {
    
    @objc func receivedNotification(notification: Notification) {
        let message = notification.object as! String
        print("Message received: \(message)")
    }
}

I know that using .publisher and onReceive this will work inside the View struct, but what's the actual reason for this code to not work?

1 Answers

Notifications matched by object, so if you subscribe by one object but post with another object, then subscriber is not fired.

Here is fixed variant. Tested with Xcode 12.1.

    NotificationCenter.default.addObserver(observerA, 
       selector: #selector(ObserverClassA.receivedNotification(notification:)), 
       name: Notification.Name("CustomNotification"), 
       object: nil)   // << subscribe for all

    let notificationToPost = Notification(name: Notification.Name("CustomNotification"), object: "This is the message", userInfo: nil)
    NotificationCenter.default.post(notificationToPost)
Related