いつもお世話になっております。
現在Moyaを使用し、APIから帰ってきたレスポンスをdecodeしようとしています。
しかし、decodeの際にregistered_atのキーがうまくdecodeできません。
帰ってくるregistered_atの値は例えば"2021-07-26"のようなyyyy-MM-dd形式です。
発生しているエラーは
▿ MoyaError ▿ objectMapping : 2 elements ▿ .0 : DecodingError ▿ typeMismatch : 2 elements - .0 : Swift.Double ▿ .1 : Context ▿ codingPath : 1 element - 0 : CodingKeys(stringValue: "registered_at", intValue: nil) - debugDescription : "Expected to decode Double but found a string/data instead." - underlyingError : nil ▿ .1 : Status Code: 200, Data Length: 137
です
レスポンスとして渡されているjsonは下記です。
{ "message": "patience has been registered", "id": 11, "money": 200, "memo": "test", "category_title": "Test", "registered_at": "2021-08-17" }
試したこと
MoyaがDate型をdecodeする際にどのような方法でdecodeするかを決めるdateDecodingStrategyで'yyyy-MM-dd'を扱うように指定してみましたが、変わらずエラーが出続けました。
コード
ApiClient.swift
class ApiClient: ApiClientInterface { private init() {} static let shared = ApiClient() func request<T>(_ request: T, callbackQueue: DispatchQueue = .main, completion: @escaping (Result<T.Response, MoyaResponseError>) -> Void) where T: ApiTargetType { let provider = MoyaProvider<T>() provider.request(request, callbackQueue: callbackQueue) { result in let decoder = JSONDecoder() decoder.dateDecodingStrategy = .formatted(.yyyyMMdd) switch result { case let .success(response): if let model = try? response.map(T.Response.self, using: decoder) { completion(.success(model)) } else if let errorModel = try? response.map(ErrorResponse.self) { completion(.failure(.badRequestError(errorModel.code))) } else { completion(.failure(.unknownError)) } case let .failure(moyaError): completion(.failure(.moyaError(moyaError))) } } } }
PatienceEntity.swift
struct PatienceEntity: Decodable { let id: Int let registeredAt: Date let memo: String let money: Int let categoryTitle: String enum CodingKeys: String, CodingKey { case id case registeredAt = "registered_at" case memo case money case categoryTitle = "category_title" } }
CreatePatienceTargetType.swift
struct CreatePatienceTargetType: ApiTargetType { typealias Response = PatienceEntity let registeredAt: Date let money: Int let memo: String let categoryTitle: String var parameters: [String: Any] { ["money": money, "memo": memo, "category_title": categoryTitle, "registered_at": registeredAt] } var path: String { "/patiences" } var method: Moya.Method { .post } var sampleData: Data { Data() } var task: Task { .requestParameters(parameters: parameters, encoding: URLEncoding.queryString) } }
ApiTargetType.swift
protocol ApiTargetType: TargetType { associatedtype Response: Decodable } extension ApiTargetType { var baseURL: URL { URL(string: "リクエストするbaseURL")! } var headers: [String: String]? { let token = TokenManager.getToken() return ["Content-Type": "application/json"] } }
DateFormatter.swift
extension DateFormatter { static let yyyyMMdd: DateFormatter = { let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd" formatter.calendar = Calendar(identifier: .gregorian) formatter.locale = Locale(identifier: "en_US_POSIX") return formatter }() }
あなたの回答
tips
プレビュー