I have an object that is a delegate. There are 6 delegate callbacks informing the delegate about the state of things. I have a MySpecialEvent
swift enum that represents these states. Can you help me figure out how to correctly initialise a SignalProducer<MySpecialEvent, NoError>
and hook the delegate calls to Producer next
Events when I instantiate this delegate object?
My expectation is (correct me pls if this is wrong) that the signal producer will be a public producer
property of the delegate object. Then I can get a reference to this producer, pass it around and basically handle events elsewhere in reactive fashion.
Initially I though that I could have a MutableProperty on the delegate object, I would change it's value inside each delegate call, and this is giving me a producer for free which I then can observe.
UPDATE: I tried this and it actually works.
But conceptually I don't like this because what I am talking about is events, not persistent state values. It's true it's an implementation detail but still. Is that approach right?
What I try to do with Functional Reactive Programming in general is remove the use of Delegates as much as possible. You are right that it seems a bit more stateful to add a MutableProperty
to the delegate class. MutableProperties are kind of a bridge between the stateless and stateful paradigms.
So, what does this mean?
Instead of creating a delegate to use for handling events when things change. Find a way to observe the events as Signals and react to events. An example is probably easiest to understand.
Say you have a modal view that you are presenting, and the presenting controller is the delegate of the presented view controller. You pass the presenting controller to the modal...
func showModal() {
let modalVC = ModalViewController()
modalVC.delegate = self
self.presentModalViewController(modalVC, animated: true)
}
func modalComplete() {
self.dismissViewControllerAnimated(true, completion: nil)
print("All Done with Modal.")
}
Then, the presented controller at some point (obviously not showing all the delegate protocol stuff)
func allDone() {
self.delegate?.modalComplete()
}
The FRP way
Replacing the delegate pattern with FRP would result is something like...
func showModal() {
let modalVC = ModalViewController()
modalVC.completionSignal
.startWithNext { [weak self] _ in
self.modalComplete()
}
self.presentModalViewController(modalVC, animated: true)
}
func modalComplete() {
self.dismissViewControllerAnimated(true, completion: nil)
print("All Done with the FRP Modal.")
}
And in your modal you would create a signal you could send something on when it's time to close the modal.
let (completionSignal, completionObserver) = SignalProducer<String, NoError>.buffer(1)
func allDone() {
completionObserver.sendNext("Whatever you want")
completionObserver.sendComplete()
}
Hope this helps. Working with both delegates and FRP can get confusing, and one of the things I like best about RAC4 is its ability to replace this cumbersome pattern.
You can also use a true Signal
rather than a SignalProducer
by defining in the modal view controller like
let (completionSignal, completionObserver) = Signal<String, NoError>.pipe()
And then just observing it on the parent view controller rather than starting and observing it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.