Always I am indebted. I'm currently using Moya and trying to decode the response returned from the API. However, when decoding, the registered_at key cannot be decoded properly. The returned registered_at value is in yyyy-MM-dd format, for example "2021-07-26". The error that is occurring is
▿ Moya Error
▿ 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."
--undergroundError: nil
▿ .1: Status Code: 200, Data Length: 137
is
The json passed as a response is below.
{
"message": "patience has been registered",
"id": 11,
"money": 200,
"memo": "test",
"category_title": "Test",
"registered_at": "2021-08-17"
}
What I tried
I tried to specify that Moya should handle'yyyy-MM-dd' in the dateDecodingStrategy, which determines how to decode the Date type, but the error continued to appear.
Code
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: "requesting 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
} ()
}