我是MVVM和RxSwift的初学者,我想在我的下一个项目中实现它。目前,我正在使用我的登录模块,一切看起来都不错,但是每次运行我的应用程序时,它都会在将文本字段绑定到我的ViewModel时触发错误说"意外发现nil,同时解包一个Optional值" 。
有人可以帮我摆脱它吗? 以下是我的表现方式:
class LoginViewController: UIViewController {
@IBOutlet weak var emailTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var loginButton: UIButton!
private var loginViewModel: UserLoginViewModel!
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
emailTextField.rx.text.orEmpty
.bind(to: loginViewModel.emailAdd)
.disposed(by: disposeBag) <---- Displays "Unexpectedly found nil while unwrapping an Optional value"
passwordTextField.rx.text.orEmpty
.bind(to: loginViewModel.password)
.disposed(by: disposeBag) <---- Displays "Unexpectedly found nil while unwrapping an Optional value"
}
}
/////loginProtocol
protocol loginProtocol {
//MARK - Input
var emailAdd: Variable<String> { get }
var password: Variable<String> { get }
var loginButtonDidTap:PublishSubject<Void>{ get }
var loginActionResult: Driver<AutenticationStatus> { get }
}
/// VIEW MODEL
class UserLoginViewModel: loginProtocol {
var emailAdd: Variable<String>
var password: Variable<String>
let loginButtonDidTap = PublishSubject<Void>()
var loginActionResult:Driver<AutenticationStatus>
init(apiService: API) {
let emailV = Variable<String>("")
let passwordV = Variable<String>("")
emailAdd = emailV
password = passwordV
let usernameAndPassword = Observable.combineLatest(emailAdd.asObservable(), password.asObservable()) {
($0, $1)
}
loginActionResult = loginButtonDidTap.asObservable()
.withLatestFrom(usernameAndPassword)
.flatMapLatest { (emailAdd, password) in
return apiService.login(email: emailAdd, password: password)
}.asDriver(onErrorJustReturn:.error(.server))
}
}
谢谢。
答案 0 :(得分:5)
在您的代码中,outlet或ViewModel可能为零。如果您的代码部分已完成,则永远不会创建loginViewModel
。
override func viewDidLoad() {
super.viewDidLoad()
// create view model
loginViewModel = UserLoginViewModel(apiService: /* your api service */)
emailTextField.rx.text.orEmpty
.bind(to: loginViewModel.emailAdd)
.disposed(by: disposeBag)
passwordTextField.rx.text.orEmpty
.bind(to: loginViewModel.password)
.disposed(by: disposeBag)
}
答案 1 :(得分:-1)
我刚刚发现错误。 LoginViewModel未初始化。 我通过初始化loginViewModel修复了错误。这是我的工作方式
var viewModel:LoginViewModel!
override func viewDidLoad() {
super.viewDidLoad()
self.viewModel = LoginViewModel(apiService: APIManager.sharedManager)
}