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

Swift 5+Alamofire+Combine+MVVM fetchData返回unknown错误如何解决

解决步骤
  • 第一步:先还原真实错误类型,不要吞掉原始错误
    你当前代码里的.mapError{_ in APIError.unknown}把所有Alamofire抛出的错误都统一转成了unknown,无法定位具体问题,先修改这部分逻辑,把错误类型对应上:
func fetchData(from endpoint:ScrapeAPI )->AnyPublisher<T, APIError>{
    return AF.request(endpoint.mockurl,
                      method: .post,
                      parameters: endpoint.parameters,
                      encoder: JSONParameterEncoder.prettyPrinted,
                      headers: endpoint.headers)
        .validate()
        .publishDecodable(type:T.self)
        .value()
        .mapError { afError -> APIError in
            // 匹配解码错误
            if let decodingError = afError.underlyingError as? DecodingError {
                return .decodingError
            } 
            // 匹配状态码错误
            else if let statusCode = afError.responseCode {
                return .errorCOde(statusCode)
            } 
            // 其他未知错误
            else {
                return .unknown
            }
        }
        .receive(on: DispatchQueue.main)
        .eraseToAnyPublisher()
}

改完后重新运行,就能确认是不是解码环节抛出的问题。

  • 第二步:打印原始响应数据,确认返回结构符合预期
    在解码逻辑前插入原始数据打印逻辑,确认返回的JSON和你预期的结构一致:
return AF.request(endpoint.mockurl,
                  method: .post,
                  parameters: endpoint.parameters,
                  encoder: JSONParameterEncoder.prettyPrinted,
                  headers: endpoint.headers)
    .validate()
    .publishData() // 先获取原始响应数据
    .handleEvents(receiveOutput: { response in
        // 将Data转成字符串打印
        if let data = response.data, let jsonStr = String(data: data, encoding: .utf8) {
            print("返回的原始JSON内容:\n\(jsonStr)")
        }
    })
    .publishDecodable(type: T.self)
    // 后续逻辑保持不变

拿到原始JSON后,和你定义的泛型T的属性逐一比对,检查字段名、字段类型是否匹配,比如JSON里的字段是蛇形命名(如user_id),而你T里的属性是驼峰(如userId),默认解码规则下就会失败。

  • 第三步:手动解码验证泛型T的匹配性
    如果确认返回JSON结构没问题,可以单独做解码验证,捕捉详细的解码错误信息,能直接定位到不匹配的字段:
// 可以用上面步骤打印拿到的原始Data,或者把.responseJSON获取到的字典转成Data
let rawJsonData = /* 从响应中获取的原始Data */
let decoder = JSONDecoder()
// 如果JSON是蛇形命名,需要添加这个配置
// decoder.keyDecodingStrategy = .convertFromSnakeCase
// 如果有自定义日期格式,也要补充对应配置
// decoder.dateDecodingStrategy = .formatted(自定义日期格式器)
do {
    let result = try decoder.decode(T.self, from: rawJsonData)
    print("解码成功: \(result)")
} catch let decodingError as DecodingError {
    print("解码失败详细信息: \(decodingError)")
    // 这里会明确输出是哪个字段缺失、类型不匹配还是键名不对应
} catch {
    print("其他错误: \(error)")
}
  • 第四步:检查Alamofire解码的Decoder配置
    Alamofire的publishDecodable方法默认使用无配置的JSONDecoder(),如果你有自定义解码规则,需要主动传入配置好的Decoder:
let customDecoder = JSONDecoder()
customDecoder.keyDecodingStrategy = .convertFromSnakeCase
// 其他自定义配置
.publishDecodable(type: T.self, decoder: customDecoder)

内容的提问来源于stack exchange,提问作者tumen khureltulga

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:24:03