Может быть, этот пример поможет вам:
//
// ExampleLiftData.swift
//
// Created by Daniel Tartaglia on 2/18/20.
// Copyright © 2020 Daniel Tartaglia. MIT License.
//
import UIKit
import RxSwift
import RxCocoa
import RxEnumKit
import EnumKit
// MARK: - ExamplePresenter
func presentExample(window: UIWindow) {
let value = PublishSubject<String>()
let storyboard = UIStoryboard(name: "Example", bundle: nil)
let controller = storyboard.instantiateInitialViewController() as! ExampleViewController
let action = controller.install(viewModel: exampleViewModel(value: value.asObservable()))
_ = action
.filter(case: ExampleAction.showRequest)
.flatMap { [unowned controller] _ in
presentRequest(on: controller, title: "", message: "Add how much?")
}
.bind(to: value)
window.rootViewController = controller
}
enum ExampleAction: CaseAccessible {
case showRequest
}
// MARK: - ExampleViewModel
func exampleViewModel(value: Observable<String>) -> (ExampleInput) -> (ExampleOutput, Observable<ExampleAction>) {
return { input in
let state = value
.compactMap { Int($0) }
.scan(0, accumulator: +)
.startWith(0)
return (
ExampleOutput(text: state.map { "\($0)" }),
input.buttonTapped.map { ExampleAction.showRequest }
)
}
}
struct ExampleInput {
let buttonTapped: Observable<Void>
}
// MARK: - ExampleView
class ExampleViewController: UIViewController, HasViewModel {
@IBOutlet weak var button: UIButton!
@IBOutlet weak var label: UILabel!
var buildOutput: (ExampleInput) -> ExampleOutput = { _ in fatalError() }
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
let input = ExampleInput(
buttonTapped: button.rx.tap.asObservable()
)
let output = buildOutput(input)
output.text.bind(to: label.rx.text).disposed(by: disposeBag)
}
}
struct ExampleOutput {
let text: Observable<String>
}
// MARK: - AlertPresenter
func presentRequest(on root: UIViewController, title: String, message: String) -> Observable<String> {
let result = PublishSubject<String>()
let controller = UIAlertController(title: title.isEmpty ? nil : title, message: message.isEmpty ? nil : message, preferredStyle: .alert)
controller.addTextField(configurationHandler: { $0.keyboardType = .numberPad })
let ok = UIAlertAction(title: "OK", style: .default, handler: { [unowned controller] _ in
result.onNext(controller.textFields?[0].text ?? "")
result.onCompleted()
})
let cancel = UIAlertAction(title: "Cancel", style: .default, handler: { _ in
result.onCompleted()
})
controller.addAction(ok)
controller.addAction(cancel)
root.present(controller, animated: true)
return result
}
Подробнее на https://github.com/danielt1263/RxEarthquake