gpt4 book ai didi

ios - ReactiveCocoa 4,根据 UI 事件和验证正确发送我的 HTTP 请求

转载 作者:搜寻专家 更新时间:2023-10-31 22:33:33 27 4
gpt4 key购买 nike

我试图理解 ReactiveCocoa 4 的一些概念,但没有找到一种方法来根据登录表单的输入正确验证和发送请求。
我当前的解决方案会在输入的每次有效更新时发送请求,这并不好。

看来我需要使用 ActionsCocoaActions 来解决我的问题,但我不明白如何正确实现它们。

这是我的代码示例:
我希望在按下登录按钮并且登录和密码字段都不为空时发送登录请求,否则我只会显示错误。
目前,当我修改输入字段时,生产者仍然活着并继续发送请求,这不太好......

我想要一个关于如何正确执行它的例子:)

登录 View 模型.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
}
}
}
}

谢谢

最佳答案

经过漫长的一夜努力,我终于找到了正确实现它的方法。
最后我想多了一点验证过程,现在简单多了。
结果:

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
}

}
}
}

关于ios - ReactiveCocoa 4,根据 UI 事件和验证正确发送我的 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34713724/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com