swiftcombinenotificationcentercurrentvaluesubject

Using NotificationCenter with CurrentValueSubject


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?


Solution

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