Using NotificationCenter with CurrentValueSubject

309 Views Asked by At

I am new to Combine. I understand we can send values with NotificationCenter's combine implementation like this:

let myNotification = Notification.Name("myNotification")

class Cat {
    var breed : String
    init(breed: String) {
        self.breed = breed
    }
}

class ClassA {

   var myCat = Cat(breed:"Ragdoll")
    
    func sendNotification() {
        NotificationCenter.default
            .post(name: myNotification,
                  object: nil,
                  userInfo: ["cat": myCat])
    }
}

class ClassB {

  let cancellable = NotificationCenter.default
        .publisher(for: myNotification).map ({ $0.userInfo!["cat"] as! Cat}).sink { cat in
            print("My cat's breed is : \(cat.breed)")
        }
}

let a = ClassA()
let b = ClassB()

a.sendNotification()

Here ClassB doesn't know that I will get data from ClassA, it only listens notifications.

When I want use a CurrentValueSubject :

class Cat {
    var breed : String
    init(breed: String) {
        self.breed = breed
    }
}

class ClassA  {
    let myCat : Cat = Cat(breed: "Ragdoll")
    
    lazy var currentValueSubject = CurrentValueSubject<Cat, Never>(myCat)
    
    func setMyCat() {
        currentValueSubject.value = myCat
    }
}


class ClassB {
    
    let classA = ClassA()
    var cancellables = [AnyCancellable]()
    
    init(){
        getMyCat()
    }
    
    func getMyCat() {
        let _ = classA.currentValueSubject
            .sink { cat in
                print("My cat's breed: \(cat.breed)")
            }.store(in: &cancellables)
    }
}

let a = ClassA()
let b = ClassB()

a.setMyCat()

Is there a way to create CurrentValueSubject and listen it by NotificationCenter, so receivers can be agnostic about the publisher's source?

I should fire NotificationCenter.default.post.... to publish changes in first method, but receivers agnostic about source. It fires changes automatically in second method, no need to post anything, but receivers are not agnostic about the source of the publisher, because we have to say "classA.currentValueSubject...."

I want to set a publisher (CurrentValueSubject or PassthroughSubject) and subscribe to it on NotificationCenter, without posting anything.

Is it possible?

1

There are 1 best solutions below

1
On BEST ANSWER

CurrentValueSubject and the Publisher of NotificationCenter are two different APIs. They are not interchangeable however their behavior is quite similar.

  • To be able to subscribe to CurrentValueSubject you must have a reference to the subject. Calling send() or setting value publishes a value.
  • The reference of NotificationCenter is its shared (default) instance and posting a notification publishes a value.