I am trying to replace delegation pattern with Combine.
The architecture of my app is a VIPER, so I need to pass the sink subscriber from one module to another. The use case is i have data from module A (list) that needs to be show to module B (detail view), and module B can also update the data so I need to get it back to module A also.
With delegates it works okay but when I use a sink subscriber I am facing an issue.
The first time I go from module A to module B, I pass the subscriber and then subscribe it to the publisher (from moduleB) it works well and the subscriber in module A receives all the events from module B.
But then when dismissing the module B and routing again from A to B, then the subscriber receives immediately a cancel event when trying to subscribe again: receive subscription: (PublishedSubject) ... receive cancel ...
I made a very simplified example to show what is happening:
Module A:
class ViewController_A: UIViewController {
var subscriber: AnySubscriber<String, Never>!
override func viewDidLoad() {
super.viewDidLoad()
createSubscriber()
}
func createSubscriber() {
let subscriber = Subscribers.Sink<String, Never>(
receiveCompletion: { completion in
print(completion)
}, receiveValue: { value in
print(value)
})
self.subscriber = AnySubscriber(subscriber)
}
func showViewControllerB() {
let viewControllerB = ViewControllerB()
viewControllerB.passSubscriber(AnySubscriber(subscriber))
}
}
Module B:
protocol MyProtocol {
var publisher: Published<String>.Publisher { get }
func passSubscriber(_ subscriber: AnySubscriber<String, Never>)
}
class ViewController_B: UIViewController, MyProtocol {
@Published var word: String = "House"
var publisher: Published<String>.Publisher { $word }
func passSubscriber(_ subscriber: AnySubscriber<String, Never>) {
publisher
.print()
.subscribe(subscriber)
}
func dismiss() {
dismiss(animated: true)
}
}
When routing..
let viewControllerA = ViewController_A()
viewControllerA.showViewController_B() // When presenting B for the first time, receiving events here
// Dismiss B here...
viewControllerA.showViewControllerB() // When presenting B again (hence subscribing again), the subscription gets cancelled here without receiving any events/values
I noticed something interesting.. When I create the subscriber again every time I route to module B instead of creating it only one time in viewDidLoad, it seems to work okay, but I am not sure why.
Does this mean that a subscriber cannot subscribe to another publisher once it subscribed to one, even when the previous publisher doesn't exist anymore?
How I can make it work in my delegation case?