質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
date

dateは、date型や日付に関する関数や処理についてのタグです

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

0回答

1349閲覧

レスポンスで返されたjsonでyyyy-MM-dd形式のdateをうまくdecodeできない

oeiqgfodgfhps

総合スコア35

date

dateは、date型や日付に関する関数や処理についてのタグです

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2021/08/18 09:12

編集2022/01/12 10:55

いつもお世話になっております。
現在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 }() }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

oeiqgfodgfhps

2021/08/18 23:52

ありがとうございます!綴りを見直しましたが、下記のようなエラーが出てしまいました。 Expected to decode Double but found a string/data instead
oeiqgfodgfhps

2021/08/19 02:07

Double型を想定しているのに文字列が来たというのが原因だと思うのですが、自動的にDate型に変換はしてくれないのでしょうか??
hoshi-takanori

2021/08/19 02:19

decoder.dateDecodingStrategy に適切な DateFormatter を指定すれば大丈夫だと思いますけど。
oeiqgfodgfhps

2021/08/19 05:07

今decoder.dateDecodingStrategyにしているDateFormatterのコードを載せたのですが、これは何かおかしいところはありますか?
hoshi-takanori

2021/08/19 08:12

ローカル時間の 0 時にするってことですよね。それで大丈夫に見えます。
oeiqgfodgfhps

2021/08/19 08:20

そうです!なんで動かないんでしょうね、、笑
oeiqgfodgfhps

2021/08/19 12:52

レスポンスで返されているjsonを載せ忘れていたので、レスポンスjsonを追記しました!
hoshi-takanori

2021/08/19 20:12

レスポンス json と PatienceEntity 型が合わない (レスポンスに memo がない) ですね。 値が省略されたり、null が返る可能性があるなら Optional 型 (String? や Int? など) を使う必要があります。 JSON のパースに関しては、実際に返ってきたものや返る可能性のあるものを集めて、Test コードや Playground などでパースできることを確認することをお勧めします。
oeiqgfodgfhps

2021/08/20 02:43

ご指摘ありがとうございます!jsonのキーはdescriptionではなくmemoでした。そして値も必ず何かしらが入ってくるものでした。 regostered_atがパースできない原因特定は難しそうですか??
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問