此篇紧接着上篇 使用Moya+ReactiveCocoa 进行网络请求 http://www.jianshu.com/p/7bf635577900
**
* 登录viewModel
*/
struct LoginViewModel {
/// 账号
let account = MutableProperty<String>("")
/// 密码
let password = MutableProperty<String>("")
/// 是否可点击
let inputIsValid = MutableProperty<Bool>(true)
//Action,接受一个类型Void,返回新的类型Bool,并且附带NetRequestError这个错误类型
lazy var loginAction: Action<Void, Bool, NetRequestError> = {
let action: Action<Void, Bool, NetRequestError> = Action(enabledIf: self.inputIsValid, { _ in
//有时我们只需要网络返回的数据的最外面一层来判断请求结果
// 所以上一篇的Comminfo Model在这里就有用了
let signal: SignalProducer<Comminfo?, NetRequestError> = NetHelper.shareInstance.requestProvider.request(RequestAPI.login(account: self.account.value, pwd: self.password.value))
.mapResponseToObject(Comminfo)
return signal
.map({ commonInfo in
guard let common = commonInfo else {
return false
}
return true
})
})
return action
}()
init() {
resetUIValues()
//这个意思是:account与password的值和inputIsValid相关联
//当account的个数是11位,并且password的个数在6到16位之间
self.inputIsValid <~ combineLatest(account.producer, password.producer)
.map { $0.0.characters.count == 11 && (6...16) ~= $0.1.characters.count }
}
}
extension LoginViewModel {
private func resetUIValues() {
account.value = ""
password.value = ""
}
}
登录控制器VC
class LoginViewController: UIViewController {
var viewModel = LoginViewModel()
private lazy var loginView: LoginView = LoginView()
这里一定要注意---一定要申明这个属性的时候,不要申明成可选的!!!!
var loginAction:CocoaAction!
override func viewDidLoad() {
super.viewDidLoad()
setUpUI()
bindViewModel()
}
}
extension LoginViewController {
private func setUpUI() {
title = "登录"
loginView.frame = view.bounds
view.addSubview(loginView)
}
//绑定view和viewModel
private func bindViewModel() {
viewModel.account <~ loginView.accountTf.rac_textSignalProducer()
viewModel.password <~ loginView.passwordTf.rac_textSignalProducer()
//绑定view上按钮的可操作和颜色与viewModel的属性
viewModel.inputIsValid.producer
.observeOn(UIScheduler())
.startWithNext { [weak self] inputIsVlid in
self?.loginView.loginBtn.enabled = inputIsVlid
self?.loginView.loginBtn.backgroundColor = inputIsVlid ? UIColor(hexString: "ff5b48") : UIColor.grayColor()
}
//绑定view上按钮的action,与viewModel的Action相关联
loginAction = CocoaAction(viewModel.loginAction, input: ())
loginView.loginBtn.addTarget(loginAction, action: CocoaAction.selector, forControlEvents: .TouchUpInside)
//发送通知---即信息
viewModel.loginAction.events.observeOn(UIScheduler())
.observeNext ({ event in
switch event {
case let .Next(_):
print("登陆成功")
case .Failed(let error):
print("+++\(error)")
default:
break
}
})
}
}