swiftreactive-cocoareactive-cocoa-3

Multiple observers of a MutableProperty in RAC3


I have a "DataManager" singleton class that handles state for my app using RAC3. It contains multiple MutablePropertys that I start and observe in various locations.

I would like to have my DataManager start or create a signal that I can observe in any view controller using my DataManager singleton, using observe() rather than start() etc. But I am stuck and am not sure how to initialize this signal in my DataManager. I've tried defining a property like

let documentUpdateSignal: Signal<Int,NSError>

let remainingDocuments = MutableProperty<Int>(0)

and then trying to start it with my mutable property's producer on init something like

override init() {
  documentUpdateSignal = remainingDocuments.producer.start(next: {
    docs in
    println("doc count \(docs)")
  })
  super.init()
}

But this doesn't work since it doesn't return a Signal<Int,NSError>

I've also attempted to create a method that returns a Signal without much luck, rather than a property... like this even though it didn't seem quite right.

func updateSignal() -> Signal<Int, NSError> {
  return remainingDocuments.producer
}

Would love help Thanks so much!


Solution

  • You've probably worked this out by now:

    var documentUpdateSignal: Signal<Int, NoError>?
    
    ....
    
    remainingDocuments.producer.startWithSignal { 
                (var signal: Signal<Int, NoError>, var disposable : Disposable) -> () in
                self.documentUpdateSignal = signal
            }
    

    I'm not sure that you'll be able to call startWithSignal from within your class' init() though, as self isn't available for capture by the block until super's init is called. Given that, I've assumed documentUpdateSignal is optional.

    Note that I've also changed the declaration of documentUpdateSignal from using NSError to NoError to suit MutableProperty's producer's signature.

    You can then observe the signal from elsewhere using:

    self.documentUpdateSignal?.observe(next: { 
                    (var value: Int) in
                    println("Mutable property = \(value)")
                }
            )