I'm using Swift 2.1 and ReactiveCocoa 4.0.4 alpha 1. I'm combining multiple signals to enable a button based on if they have valid inputs. The following code works correctly, but I'm wondering if there is a more elegant and efficient way of accomplishing this with the ReactiveCocoa APIs, as well as if this is the proper way to be using the API in Swift.
let sig0 = firstTextField.rac_textSignal()
.max(self.firstTextField, max: maxLength)
.map{ next in
if let str = next as? String {
return str.characters.count > 0
} else {
return false
}
}
let sig1 = secondTextField.rac_textSignal()
.max(self.secondTextField, max: maxLength)
.map{ next in
if let str = next as? String {
return str.characters.count > 0
} else {
return false
}
}
let combined = RACSignal.combineLatest([sig0, sig1])
combined.subscribeNext { (obj: AnyObject!) -> Void in
let tup = obj as! RACTuple
let valid = (tup.first as! Bool) && (tup.second as! Bool)
self.button.enabled = valid
}
1 Answer 1
I'm familiar with RxSwift, not RAC. :-( That said, I think I can say something constructive about this code...
sig0
and sig1
need more descriptive names.
I would be inclined to break up the combined.subscribeNext
function. Something more like:
let buttonEnabled = RACSignal.combineLatest([sig0, sig1])
.map { obj in
let tup = obj as! RACTuple // Wow RAC doesn't return type safe values?
return (tup.first as! Bool) && (tup.second as! Bool)
}
buttonEnabled.subscribeNext { obj in
let valid = obj as! Bool
self.button.enabled = valid
}
I strongly suspect that there is a function for mapping the buttonEnabled signal directly to the button though, maybe with an Action
? You should look into that.
-
\$\begingroup\$ This looks like a good solution, thanks! I've actually moved to RxSwift since this question because I found it to work much better with Swift \$\endgroup\$Chris– Chris2016年04月02日 23:35:46 +00:00Commented Apr 2, 2016 at 23:35