RXSwift Binding在展开Optional值时返回意外发现的nil

vid*_*joe -2 mvvm ios swift rx-swift swift4

我是MVVM和RxSwift的初学者,我想在我的下一个项目中实现它.目前,我正在使用我的登录模块,一切看起来都很好,但是每次运行我的应用程序时,它都会在将文本字段绑定到我的ViewModel时发出错误,说"在解开一个Optional值时意外发现了nil".

任何人都可以帮我摆脱它吗?我是这样做的:

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))
    }
}
Run Code Online (Sandbox Code Playgroud)

这是截图

谢谢.

小智 5

在您的代码中,出口或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)
}
Run Code Online (Sandbox Code Playgroud)