RxSwift+MVVM+AppCoordinator登录场景subscribe回调不触发问题求助
问题修复方案
核心问题定位
你遇到的回调无法触发的根本原因是 LoginViewController 中重复创建了 LogInViewModel 实例:
LogInCoordinator初始化时已经给LoginViewController的viewModel属性赋值,并且订阅了该实例的didLogIn、logInDidFail事件- 你在
LoginViewController的viewDidLoad方法中又重新初始化了一次viewModel,后续点击按钮触发的是新实例的登录方法,Coordinator 完全没有订阅新实例的事件,自然收不到任何回调
其他问题点
SessionService的登录请求逻辑不规范:当前代码忽略 Alamofire 真实返回结果,固定返回成功,无法正确处理接口报错、解码失败等异常场景- 登录请求用 GET 方法不符合常规业务规范,账号密码会拼接在 URL 中存在安全风险
- 多处重复创建
SessionService实例,不利于全局统一管理会话状态
修复代码
1. 修复 LoginViewController 重复初始化 ViewModel 的问题
打开 LoginViewController.swift,删除 viewDidLoad 中重复创建 ViewModel 的代码:
override func viewDidLoad() { super.viewDidLoad() self.emailTextField.placeholder = "Email or Username" self.passwordTextField.placeholder = "Password" self.passwordTextField.isSecureTextEntry = true // 删掉下面这行重复初始化的代码即可 // viewModel = LogInViewModel(authentication: SessionService()) self.setUpBindings() }
2. 修复 SessionService 登录请求逻辑
打开 SessionService.swift,修改登录方法正确处理请求结果,同时将请求方法改为 POST:
func login(username: String, password: String) -> Single<AuthResponse> { let formHeader: HTTPHeaders = [ "Content-Type": "application/x-www-form-urlencoded" ] let parameters: Parameters = [ "username": username, "password": password ] let decoder = JSONDecoder() return Single<AuthResponse>.create { single in let request = AF.request(API.auth, method: .post, parameters: parameters, headers: formHeader) .responseDecodable(of: AuthResponse.self, decoder: decoder) { response in switch response.result { case .success(let authResponse): // 若后端有业务状态码,可在此处增加判断,不符合成功条件则返回自定义错误 single(.success(authResponse)) case .failure(let error): single(.failure(error)) } } return Disposables.create { request.cancel() } } }
可选优化建议
可以将 AppCoordinator 中初始化的 SessionService 实例向下传递给 LogInCoordinator 和 LogInViewModel,避免重复创建实例,方便后续统一管理登录态、配置请求公共参数等。
内容的提问来源于stack exchange,提问作者stack
相关产品推荐
相关产品推荐

