使用Reactive Cocoa的简单文本字段验证器

时间:2016-03-07 18:17:49

标签: swift reactive-cocoa

我正在操场上测试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)

1 个答案:

答案 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,因为它需要一个函数并返回一个信号。但它只允许一些值通过,允许您仅根据有效输入发出网络请求。