Я пытаюсь понять некоторые концепции ReactiveCocoa 4 и не нашел способ правильно проверить и отправить запрос на основе входов из формы входа ,
Мое текущее решение отправляет запросы по каждому действительному обновлению моих входов, что не очень хорошо.ReactiveCocoa 4, правильно отправить мой HTTP-запрос на основе события пользовательского интерфейса и проверки
Кажется, мне нужно использовать Actions
и CocoaActions
, чтобы исправить мою проблему, но я не понимаю, как правильно их реализовать.
Вот мой пример кода:
Я хочу, чтобы запрос на вход был отправлен при нажатии кнопки входа в систему, а поля ввода и пароля не пусты, иначе я просто покажу ошибку.
В настоящее время производитель остается в живых и продолжают посылать запросы, когда я изменить поля ввода, которые не очень хорошо ...
Я хотел бы пример того, как сделать это правильно :)
LoginViewModel.swift
class LoginViewModel {
let login = MutableProperty<String>("")
let password = MutableProperty<String>("")
init() {
}
func logIn() -> SignalProducer<Int, IntranetError> {
return SignalProducer {
observer, disposable in
combineLatest(self.login.producer, self.password.producer)
.promoteErrors(Moya.Error)
.filter { (credentials : (String, String)) in
guard credentials.0.length > 0 else {
observer.sendFailed(IntranetError.MissingLoginError)
return false
}
guard credentials.1.length > 0 else {
observer.sendFailed(IntranetError.MissingPasswordError)
return false
}
return true
}
.flatMap(.Latest) { (credentials : (String, String)) -> SignalProducer<User, Moya.Error> in
let login = credentials.0
let password = credentials.1
return IntranetProvider.request(Intranet.LogIn(login, password)).filterSuccessfulStatusCodes()
.mapObject(User)
}
.start { (event) -> Void in
switch event {
case .Next(let user):
UserManager.sharedManager.user = user;
print(user)
observer.sendCompleted()
case .Failed(let error):
observer.sendFailed(.MoyaError(error))
default:
break
}
}
}
}
}
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
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func connectButtonTouched(sender: AnyObject) {
loginAsked()
}
func loginAsked() -> Void {
SVProgressHUD.showWithMaskType(.Black)
viewModel.logIn().throttle(0.5, onScheduler: QueueScheduler.mainQueueScheduler).start { (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
}
}
}
}
Благодаря