使用Moya解析API返回的yyyy-MM-dd格式日期时解码失败的问题求助
看起来你遇到的问题是解码API响应时,系统错误地尝试把registered_at的字符串日期解析成Double类型——这说明你配置的dateDecodingStrategy可能没有被正确应用到解码流程里,或者有其他细节没处理到位。我来帮你一步步解决:
核心问题分析
错误信息里明确提到Expected to decode Double but found a string / data instead,虽然你的PatienceEntity里registeredAt是Date类型,但解码过程中并没有用你配置好的JSONDecoder去处理,导致系统默认尝试把字符串转成Double(这是JSONDecoder默认的日期解码策略,把日期转成时间戳Double)。
解决方案1:改用手动解码,确保Decoder生效
Moya的response.map(_:using:)有时候可能因为内部逻辑或者try?的吞错行为,导致自定义Decoder没有生效。我们可以改成手动取响应数据,用自己的Decoder解码:
修改ApiClient.swift里的成功分支代码:
case let .success(response): let decoder = JSONDecoder() decoder.dateDecodingStrategy = .formatted(.yyyyMMdd) do { // 手动解码响应数据 let model = try decoder.decode(T.Response.self, from: response.data) completion(.success(model)) } catch let decodingError { // 打印错误方便调试,不要用try?吞掉 print("Decoding error details: \(decodingError)") // 再尝试解析错误模型 do { let errorModel = try response.map(ErrorResponse.self) completion(.failure(.badRequestError(errorModel.code))) } catch { completion(.failure(.unknownError)) } }
解决方案2:修复请求参数的日期格式(潜在问题)
另外注意到你在CreatePatienceTargetType的参数里直接传了Date类型的registeredAt,Moya默认会把Date编码成时间戳(Double类型),但你的API期望的是yyyy-MM-dd格式的字符串。这会导致请求参数不符合API要求,可能引发后续问题,所以需要把Date转成字符串再传:
修改CreatePatienceTargetType.swift的parameters:
var parameters: [String: Any] { // 把Date转成API需要的字符串格式 let dateString = DateFormatter.yyyyMMdd.string(from: registeredAt) return ["money": money, "memo": memo, "category_title": categoryTitle, "registered_at": dateString] }
额外建议:避免用try?吞掉错误
你之前用try?会直接忽略解码错误的具体信息,很难排查问题。改用do-catch可以捕获到详细的错误日志,帮你快速定位问题。
按照这两个修改,应该就能正确解析registered_at字段了。
内容的提问来源于stack exchange,提问作者hime_chann____

