我正在操场上测试ReactiveCocoa。我想在执行网络请求之前测试字符串的有效性。
我不确定如何组合文本域信号和验证信号。标记为[??] =>的代码部分过滤器的正确方法是什么?
var textField = UITextField()
textField.text = "http://localhost:3000/users.json"
let searchStringsProducer = textField.rac_textSignal().toSignalProducer()
let searchStringValidProducer = searchStringsSignal.toSignalProducer().map{
text in
(text as! String).containsString("http")
}
// this produces a ReactiveCocoa.SignalProducer<(Optional<AnyObject>, Bool), NSError>.
let searchStringCombined = combineLatest(searchStringsProducer, searchStringValidProducer)
// turns the simple search results into a signal
let searchResults = searchStringCombined
// [??] i would like to ONLY execute on the rest of the actions if it is valid
.map{ // what do i do here before passing on to the network API }
.flatMap(FlattenStrategy.Latest) {
latestStr -> SignalProducer<[AnyObject], NSError> in
return requestJSON(latestStr, parameters: nil)
.flatMapError { error in
print("Network error occurred: \(error)")
return SignalProducer.empty
}
}.observeOn(uis)
答案 0 :(得分:2)
let searchStringValidProducer = searchStringsSignal.toSignalProducer().map { text in
(text as! String).containsString("http")
}
let searchStringCombined = combineLatest(searchStringsProducer, searchStringValidProducer)
这种模式令人不安,因为当searchStringsProducer
发送一个值时,searchStringCombined
将发送两个值 - 一个用于新字符串,一个用于新布尔值。这样定义这个信号会更简洁:
let searchStringCombined = searchStringsSignal.toSignalProducer().map { text in
(text, (text as! String).containsString("http"))
}
这会给你相同的结果。
但您根本不需要定义searchStringCombined
,除非您在其他地方使用它。您应该能够使用简单的filter
:
searchStringsSignal.toSignalProducer().filter({ text in
(text as! String).containsString("http")
}).map({
/* whatever goes here */
}).flatMap(FlattenStrategy.Latest) {
/* perform network request */
}
filter
有点像map
,因为它需要一个函数并返回一个信号。但它只允许一些值通过,允许您仅根据有效输入发出网络请求。