Last active
March 14, 2019 01:02
-
-
Save andschdk/578afffeb375f5db7bb11e8a8443de82 to your computer and use it in GitHub Desktop.
Simple protocol to ensure only one item is presented at a time. It is based on the Rx `.zip` operator. As an example it is used for presenting alerts one at a time. This is great when dealing with arbitrary number of alerts that can appear because of uncontrollable factors such as errors.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import RxSwift | |
public protocol SerialPresenter { | |
associatedtype T | |
var incoming: Observable<T> { get } | |
var dismissCurrent: Observable<Void> { get } | |
var present: Observable<T> { get } | |
} | |
public extension SerialPresenter { | |
var present: Observable<T> { | |
return Observable.zip( | |
incoming, | |
dismissCurrent.startWith(()) | |
) { content, _ in content } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import RxSwift | |
import RxOptional | |
import SerialPresenter | |
class ViewController: UIViewController { | |
private var presentAlert: Observable<UIAlertController>! | |
private let dismissAlert = PublishSubject<Void>() | |
private let bag = DisposeBag() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
let alertOne = Observable.just(()) | |
.delay(5, scheduler: MainScheduler.instance) | |
.map { [weak self] _ in self?.createAlert(with: "Alert 1") } | |
.filterNil() | |
let alertTwo = Observable.just(()) | |
.delay(10, scheduler: MainScheduler.instance) | |
.map { [weak self] _ in self?.createAlert(with: "Alert 2") } | |
.filterNil() | |
let alertThree = Observable.just(()) | |
.delay(10, scheduler: MainScheduler.instance) | |
.map { [weak self] _ in self?.createAlert(with: "Alert 3") } | |
.filterNil() | |
presentAlert = Observable.merge( | |
alertOne, | |
alertTwo, | |
alertThree | |
) | |
present | |
.subscribe(onNext: { [weak self] vc in | |
self?.present(vc, animated: true, completion: nil) | |
}) | |
.disposed(by: bag) | |
} | |
private func createAlert(with title: String) -> UIAlertController { | |
let dismissAction = UIAlertAction(title: "OK", style: .cancel) { [weak self] _ in | |
self?.dismissAlert.onNext(()) | |
} | |
let vc = UIAlertController(title: title, message: nil, preferredStyle: .alert) | |
vc.addAction(dismissAction) | |
return vc | |
} | |
} | |
extension ViewController: SerialPresenter { | |
typealias T = UIAlertController | |
var incoming: Observable<UIAlertController> { | |
return presentAlert | |
} | |
var dismissCurrent: Observable<Void> { | |
return dismissAlert | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
GIF ⌛