You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 05:00:01