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

Swift Combine如何在服务层处理接口响应并返回可选Error类型

正确实现方案

你可以直接通过Combine的map操作符转换响应流,无需提前订阅,也不用额外的闭包回调,完全符合响应式设计规范:

1. 改造AuthService的registerAccount方法

class AuthService {
    private let apiClient: APIClient = APIClient()
    private var guid: String?
    private var cancellableSet = Set<AnyCancellable>()

    func registerAccount(params: [String: Any]) -> AnyPublisher<Error?, Never> {
        let registerRequest = RegisterAccountRequest(params: params)
        return apiClient.request(request: registerRequest)
            .map { [weak self] dataResponse in
                // 存储guid逻辑
                if let guid = dataResponse.value?.guidFlow {
                    self?.guid = guid
                }
                // 如需处理业务错误(比如接口200但返回错误码)可在这里补充判断
                // if let value = dataResponse.value, value.code != 0 {
                //     return NSError(domain: "BizError", code: value.code, userInfo: [NSLocalizedDescriptionKey: value.msg])
                // }
                // 直接返回网络层错误,无错误返回nil
                return dataResponse.error
            }
            .eraseToAnyPublisher()
    }
}

2. ViewModel侧调用适配

func registerAccount() {
    authService.registerAccount(params: params)
        .sink { [weak self] error in
            if let error = error {
                // 处理登录失败逻辑,比如提示错误
                print("登录失败: \(error.localizedDescription)")
            } else {
                // 处理登录成功逻辑,比如跳转页面
                print("登录成功")
            }
        }
        .store(in: &cancellableSet)
}

方案说明

  • 你之前提前sink再返回原Publisher的写法会触发两次独立订阅,导致重复发起网络请求,本方案全程通过操作符转换流,只会发起一次请求
  • 所有逻辑都在Combine响应链内处理,没有引入额外的闭包回调,符合SwiftUI的响应式设计规范
  • 最终返回的Publisher输出正好是你需要的Error?类型,无错误时输出nil,有错误时输出对应错误实例。

内容的提问来源于stack exchange,提问作者Alexandru Vasiliu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:39:00