Skip to content

Instantly share code, notes, and snippets.

@rnkyr
Created December 14, 2020 10:34
Show Gist options
  • Select an option

  • Save rnkyr/6d20e9f5f01a779ed05ca47eec702bc1 to your computer and use it in GitHub Desktop.

Select an option

Save rnkyr/6d20e9f5f01a779ed05ca47eec702bc1 to your computer and use it in GitHub Desktop.
import UIKit
import RxSwift
public typealias Alert = UIAlertController
public final class AlertBuilder {
private struct Action {
let title: Observable<String>
let style: UIAlertAction.Style
let handler: ((UIAlertAction) -> Void)?
func convert() -> Observable<UIAlertAction> {
return title.map { title in
UIAlertAction(title: title, style: self.style, handler: self.handler)
}
}
}
private var _title: Observable<String> = Observable.just("")
private var _message: Observable<String> = Observable.just("")
private var _preferredStyle: UIAlertController.Style = .alert
private var actions: [Action] = []
public init() {}
public func title(_ title: Observable<String>) -> Self {
_title = title
return self
}
public func message(_ message: Observable<String>) -> Self {
_message = message
return self
}
public func preferredStyle(_ preferredStyle: UIAlertController.Style) -> Self {
_preferredStyle = preferredStyle
return self
}
public func action(_ title: Observable<String>, style: UIAlertAction.Style = .default, handler: ((UIAlertAction) -> Void)? = nil) -> Self {
actions.append(Action(title: title, style: style, handler: handler))
return self
}
public func build() -> Observable<Alert> {
let actions: Observable<[UIAlertAction]> = self.actions.isEmpty
? Observable.just([])
: Observable.combineLatest(self.actions.map { $0.convert() })
return Observable
.combineLatest(
actions, _title, _message, Observable.just(_preferredStyle)
)
.map { actions, title, message, style -> UIAlertController in
let controller = UIAlertController(
title: title.isEmpty ? nil : title,
message: message.isEmpty ? nil : message,
preferredStyle: style
)
actions.forEach { action in
controller.addAction(action)
}
return controller
}
.take(1)
}
public func present(in controller: UIViewController?, disposeBag: DisposeBag) {
build()
.subscribe(onNext: { [weak controller] alert in
controller?.present(alert: alert)
})
.disposed(by: disposeBag)
}
}
extension UIViewController {
public func present(alert: Alert) {
present(alert, animated: true)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment