经过长时间的工作,我终于找到了如何正确地实现它。
最后,我想得有点过头了,验证过程现在简单多了。
结果:
LoginViewModel.swift
class LoginViewModel {
let login = MutableProperty<String>("")
let password = MutableProperty<String>("")
var loginAction : Action<(String, String), User, IntranetError>!
var cocoaActionLogin : CocoaAction!
init() {
loginAction = Action { (let login, let password) in
return SignalProducer {
observer, disposable in
guard login.length > 0 else {
observer.sendFailed(IntranetError.MissingLoginError)
return
}
guard password.length > 0 else {
observer.sendFailed(IntranetError.MissingPasswordError)
return
}
print("SENT")
IntranetProvider.request(Intranet.LogIn(login, password))
.filterSuccessfulStatusCodes()
.mapObject(User)
.start { (event) in
switch event {
case .Next(let user):
UserManager.sharedManager.user = user;
print(user)
observer.sendCompleted()
case .Failed(let error):
observer.sendFailed(.MoyaError(error))
default:
observer.sendCompleted()
}
}
}
}
cocoaActionLogin = CocoaAction(loginAction) { _ in
return (self.login.value, self.password.value)
}
}
}
LoginViewController.swift
class LoginViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var loginTextField: FramedTextField!
@IBOutlet weak var passwordTextField: FramedTextField!
@IBOutlet weak var connectButton: UIButton!
let viewModel : LoginViewModel = LoginViewModel()
override func viewDidLoad() {
super.viewDidLoad()
viewModel.login <~ loginTextField.rac_text
viewModel.password <~ passwordTextField.rac_text
connectButton.addTarget(self.viewModel.cocoaActionLogin, action: CocoaAction.selector, forControlEvents: .TouchUpInside)
self.viewModel.loginAction.events
.observeOn(UIScheduler())
.observeNext { (event) in
switch event {
case .Completed:
SVProgressHUD.dismiss()
self.connectionSuccessfull()
case .Failed(let error):
switch error {
case .MissingPasswordError :
SVProgressHUD.showErrorWithStatus(NSLocalizedString("Missing password", comment: "User password is missing"))
case .MissingLoginError :
SVProgressHUD.showErrorWithStatus(NSLocalizedString("Missing login", comment: "User login is missing"))
case .MoyaError(let error) :
SVProgressHUD.showErrorWithStatus(error.toString())
default :
SVProgressHUD.showErrorWithStatus(NSLocalizedString("Internal error, please try again later", comment: ""))
}
default:
break
}
}
}
}