Replacing Delegate With Combine Publisher
Making callback action between two view controllers using combine publisher .
Suppose that we have two view controllers (firstVC , secondVC) and when need to make action or send data back to the firstVC when you are in secondVC .
- First ViewController
import UIKit
import Combine
class FirstController: UIViewController {
?? ?
? ? @IBOutlet weak var showWelcomMessageLable: UILabel!
? ? var anyCancalableSet = Set<AnyCancellable>()
? ? override func viewDidLoad() {
? ? ? ? super.viewDidLoad()
? ? }
? ? @IBAction func didTappedPresentSecondVC(_ sender: Any) {
? ? ? ? presentSecondViewController()
? ? }
?? ?
? ? private func presentSecondViewController(){
? ? ? ? let secondVC = SecondViewController()
? ? ? ? secondVC.welcomMessageSubject
? ? ? ? ? ? .compactMap({$0})
? ? ? ? ? ? .assign(to: \.text, on: showWelcomMessageLable)
? ? ? ? ? ? .store(in: &anyCancalableSet)
// here you bind the welcomeMessageSubject with it's label
? ? ? ? self.present(secondVC, animated: true)
? ? }
}
- Second ViewController
import UIKit
import Combine
class SecondViewController: UIViewController {
??
?private(set) var welcomMessageSubject = PassthroughSubject<String,Never>()
? ? override func viewDidLoad() {
? ? ? ? super.viewDidLoad()
? ? }
?? ?
? ? @IBAction func didTapSendWelcomMessage(_ sender: Any) {
? ? ? ? dismiss(animated: true){
? ? ? ? ? ? self.welcomMessageSubject.send("Hello Futrue ??")
? ? ? ? }
? ? }
}
领英推荐
-You can use another way open the second viewController with future then send the future promise to the second viewController and when you want to make the callback action just fire promise success event
The First ViewController will be like this :-
class FirstViewController: UIViewController {
? ? var anyCancalableSet = Set<AnyCancellable>()
? ? @IBOutlet weak var showWelcomMessageLable: UILabel!
? ? override func viewDidLoad() {
? ? ? ? super.viewDidLoad()
? ? }
? ? @IBAction func didTapedShowVC(_ sender: Any) {
? ? ? ? showSecondVC()
? ? ? ? ? ? .compactMap({$0})
? ? ? ? ? ? .assign(to: \.text, on: showWelcomMessageLable)
? ? ? ? ? ? .store(in: &anyCancalableSet)
? ? }
? ? private func showSecondVC()-> AnyPublisher<String,Never> {
?? ? ? return Future { promise in
?? ? ? ? ? let secondVC = SecondViewController()
?? ? ? ? ? secondVC.promise = promise
// Passing promise result to the Second ViewController to use it to fire the action callback
?? ? ? ? ? self.present(secondVC, animated: true)
?? ? ? }
?? ? ? .eraseToAnyPublisher()
? ? }
}
The Second ViewController will be like this :-
class SecondViewController: UIViewController {
? ? typealias FutureResult =? ((Result<String, Never>) -> Void)
? ? var promise: FutureResult?
? ? override func viewDidLoad() {
? ? ? ? super.viewDidLoad()
? ? }
? ? @IBAction func didTapSendValues(_ sender: Any) {
? ? ? ? dismiss(animated: true){
? ? ? ? ? ? self.promise?(.success("Hello Futrue ??"))
// we are using promise to fire the
? ? ? ? }
? ? }
}
- I hope it help .
- Thank you for reading .
My Regards , Happy Coding... ??????
Senior iOS Engineer @ Yassir
2 年Combine is like magic ?? I really enjoy it