私は Swift と ReactiveCocoa の初心者でもあります。MVVM と Reactive Cocoa v3.0-beta.4 フレームワークを使用して、このセットアップを実装し、新しい RAC 3 フレームワークの基本を学びたいと思います。
テキスト フィールドがあり、検証のためにテキスト入力に 3 文字以上を含める必要があります。テキストが検証に合格すると、下のボタンが有効になります。ボタンがタッチダウン イベントを受け取ったら、ビュー モデルのプロパティを使用してアクションをトリガーしたいと考えています。
現時点では RAC 3.0 ベータ版に関するリソースがほとんどないため、フレームワークの Github リポジトリの QA を読んで、次のことを実装しました。これが私がこれまでに思いついたものです:
ViewModel.swift
class ViewModel {
var text = MutableProperty<String>("")
let action: Action<String, Bool, NoError>
let validatedTextProducer: SignalProducer<AnyObject?, NoError>
init() {
let validation: Signal<String, NoError> -> Signal<AnyObject?, NoError> = map ({
string in
return (count(string) > 3) as AnyObject?
})
validatedTextProducer = text.producer.lift(validation)
//Dummy action for now. Will make a network request using the text property in the real app.
action = Action { _ in
return SignalProducer { sink, disposable in
sendNext(sink, true)
sendCompleted(sink)
}
}
}
}
ViewController.swift
class ViewController: UIViewController {
private lazy var txtField: UITextField = {
return createTextFieldAsSubviewOfView(self.view)
}()
private lazy var button: UIButton = {
return createButtonAsSubviewOfView(self.view)
}()
private lazy var buttonEnabled: DynamicProperty = {
return DynamicProperty(object: self.button, keyPath: "enabled")
}()
private let viewModel = ViewModel()
private var cocoaAction: CocoaAction?
override func viewDidLoad() {
super.viewDidLoad()
view.setNeedsUpdateConstraints()
bindSignals()
}
func bindSignals() {
viewModel.text <~ textSignal(txtField)
buttonEnabled <~ viewModel.validatedTextProducer
cocoaAction = CocoaAction(viewModel.action, input:"Actually I don't need any input.")
button.addTarget(cocoaAction, action: CocoaAction.selector, forControlEvents: UIControlEvents.TouchDown)
viewModel.action.values.observe(next: {value in
println("view model action result \(value)")
})
}
override func updateViewConstraints() {
super.updateViewConstraints()
//Some autolayout code here
}
}
RACUtilities.swift
func textSignal(textField: UITextField) -> SignalProducer<String, NoError> {
return textField.rac_textSignal().toSignalProducer()
|> map { $0! as! String }
|> catch {_ in SignalProducer(value: "") }
}
この設定では、ビュー モデルのテキストが 3 文字を超える場合にボタンが有効になります。ユーザーがボタンをタップすると、ビュー モデルのアクションが実行され、戻り値を true として取得できます。ここまでは順調ですね。
私の質問は: ビュー モデルのアクション内で、保存されたテキスト プロパティを使用し、それを使用してネットワーク リクエストを行うようにコードを更新したいと考えています。したがって、View Controller 側からの入力は必要ありません。Action プロパティへの入力を要求しないようにするにはどうすればよいですか?