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

为Publisher扩展自定义输出类型,将特定ApiError转为.success

解决Swift Publisher中特殊错误转成功的自定义Output方案

1. 定义自定义Output枚举

需要一个能同时容纳正常输出和2233特殊成功场景的类型,用枚举实现最清晰:

// 枚举可根据需求调整关联值类型,若特殊场景无需额外值可改为无关联case
enum CustomOutput<NormalOutput> {
    // 对应Publisher正常发送的输出
    case normal(NormalOutput)
    // 对应code=2233的特殊成功场景,参考示例用Bool,也可替换为Void
    case code2233Success(Bool)
}

// 简化版(特殊场景无额外值):
// enum CustomOutput<NormalOutput> {
//     case normal(NormalOutput)
//     case code2233Success
// }

2. 修改Publisher扩展方法

调整扩展方法的回调签名,让Result使用自定义的CustomOutput,并在捕获到目标错误时返回对应成功枚举:

extension Publisher {
    func sinkToCustomResult(_ result: @escaping ((Result<CustomOutput<Self.Output>, Self.Failure>) -> Void)) -> AnyCancellable {
        return sink(receiveCompletion: { completion in
            switch completion {
            case .failure(let error):
                // 匹配目标ApiError及code=2233的情况
                if let apiError = error as? ApiError,
                   let globalError = apiError.globalErrors.first,
                   globalError.code == 2233 {
                    // 返回特殊成功场景,根据枚举定义调整参数
                    result(.success(.code2233Success(true)))
                    // 简化版写法:result(.success(.code2233Success))
                    return // 必须终止后续代码,避免重复发送失败回调
                }
                // 其他错误正常返回失败
                result(.failure(error))
            case .finished:
                break
            }
        }, receiveValue: { output in
            // 正常输出返回normal枚举
            result(.success(.normal(output)))
        })
    }
}

3. 使用示例

调用扩展方法时,通过枚举区分两种成功场景:

// 假设你有一个返回String类型的Publisher
let samplePublisher: AnyPublisher<String, ApiError> = ...

samplePublisher.sinkToCustomResult { result in
    switch result {
    case .success(let customOutput):
        switch customOutput {
        case .normal(let content):
            print("正常请求成功,内容:\(content)")
        case .code2233Success(let value):
            print("捕获到code=2233,按成功处理,值:\(value)")
            // 简化版处理:print("捕获到code=2233,按成功处理")
        }
    case .failure(let error):
        print("请求失败,错误:\(error)")
    }
}

关键说明

  • 枚举的作用:原Result的Output类型固定为Publisher的输出类型,无法同时兼容正常输出和特殊标记,枚举能明确区分两种成功场景,避免类型混淆。
  • return的必要性:匹配到2233错误后必须终止后续代码,否则会同时发送成功和失败回调,导致逻辑错误。

内容的提问来源于stack exchange,提问作者Marta Paniti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 22:50:37