Добавьте счетчик при выполнении запроса moya с помощью RxSwift и mvvm и отклоните его, когда пользователь получит ответ

У меня есть приложение, в котором я пытаюсь реализовать RxSwift с использованием MVVM.

У меня есть SignInViewModel, где я делаю проверку, и я обновляю логин, который можно наблюдать, с помощью логического ответа на остальные, который я слушаю.

В классе контроллера, когда когда-либо проходят проверки, включается кнопка входа.

Аналогичным образом я хочу иметь возможность запускать счетчик по нажатию кнопки и отклонять, когда пользователь получает ответ.

Когда я пытаюсь прослушать loginObservable из модели представления в классе контроллера. он не попадает в блок привязки.

Я не могу понять, в чем проблема.

Любая помощь будет оценена

Ниже моя SignInViewModel

class SignInViewModel {

    let validatedEmail: Observable<Bool>
    let validatedPassword: Observable<Bool>
    let loginEnabled: Observable<Bool>
    let loginObservable: Observable<Bool>

    init(username: Observable<String>,
         password: Observable<String>,
         loginTap: Observable<Void>) {

        self.validatedEmail = username
            .map { $0.characters.count >= 5 }
            .shareReplay(1)

        self.validatedPassword = password
            .map { $0.characters.count >= 2 }
            .shareReplay(1)

        self.loginEnabled = Observable.combineLatest(validatedEmail, validatedPassword ) { $0 && $1 }
        let userAndPassword = Observable.combineLatest(username, password) {($0,$1)}

        self.loginObservable = loginTap.withLatestFrom(userAndPassword).flatMapLatest{ (username, password) in
            return RestService.login(username: username, password: password).observeOn(MainScheduler.instance)
        }
    }
}

Ниже приведен класс moyaRequest

final class MoyaRequest{
    func signIn(userData: Creator) -> Observable<Response> {
            return provider.request(.signIn(userData))
                .filter(statusCode: 200)
        }
}

Ниже приводится мой класс RestService

class RestService:NSObject {

    static var moyaRequest = MoyaRequest()
    static var disposeBag = DisposeBag()

static func login(username: String, password: String) -> Observable<Bool> {
    let userData = Creator()
    userData?.username = username
    userData?.password = password
    print("Username password", userData?.username, userData?.password)
    return  Observable.create { observer in moyaRequest.signIn(userData: userData!).subscribe{ event -> Void in
        switch event {

        case .next(let response):
            print("Response",response)

        case .error(let error):
            let moyaError: MoyaError? = error as? MoyaError
            let response: Response? = moyaError?.response
            let statusCode: Int? = response?.statusCode

            print("Sample Response code error" + String(describing: statusCode))
        default:
            break
        }
        }
        return Disposables.create()
    }

}

}

Я пытаюсь связать модель представления в классе контроллера.

class SignInViewController: UIViewController{

    let disposeBag = DisposeBag()
    @IBOutlet weak var passwordTextfield: UITextField!
    @IBOutlet weak var usernameTextfield: UITextField!

    private var viewModel : SignInViewModel!
    @IBOutlet weak var signInButton: UIButton!
    override func viewDidLoad() {
        setUpRxViewModel()

    }

    func setUpRxViewModel(){
        self.viewModel = SignInViewModel(username: self.usernameTextfield.rx.text.orEmpty.asObservable(),
                                         password: self.passwordTextfield.rx.text.orEmpty.asObservable(),
                                         loginTap: self.signInButton.rx.tap.asObservable())

        self.viewModel.loginEnabled.bind{ valid  in
            self.signInButton.isEnabled = valid
            }.addDisposableTo(disposeBag)

        self.viewModel.loginObservable.bind{ input in
            print("Login Clicked")
            }.addDisposableTo(disposeBag)


    }
}

1 ответ

Решение

В вашем login Метод, которым вы не отправляете какие-либо события вашему наблюдателю. Так должно быть:

case .next(let response):
            observer.on(.next(true))
            print("Response",response)

case .error(let error):
            observer.on(.error(error))
            //or observer.on(.next(false)) if you intend to use Bool as indicator of operation success which is a very bad idea.
            let moyaError: MoyaError? = error as? MoyaError
            let response: Response? = moyaError?.response
            let statusCode: Int? = response?.statusCode

кроме того, я рекомендую вам использовать RxMoyaProvider везде, если вы используете Мойя с RxSwift. С помощью Observable.create обычно означает, что вы делаете что-то не так.

Вы также не должны отфильтровывать события на основе кода состояния на уровне сетевого запроса, потому что если что-то пойдет не так, вы не получите никакого события в вашей цепочке.

Другие вопросы по тегам