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

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

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

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

JSON

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

Swift

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

受付中

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

oeiqgfodgfhps
oeiqgfodgfhps

総合スコア0

date

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

JSON

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

Swift

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

0回答

0評価

0クリップ

8閲覧

投稿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, "description": null, "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 }() }

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

hoshi-takanori
hoshi-takanori

2021/08/18 23:14

CodingKeys の綴りを見直しましょう。また、CodingKeys にはすべての属性を指定する必要があります。 https://gtech\.hatenablog\.com/entry/2018/05/30/113153
oeiqgfodgfhps
oeiqgfodgfhps

2021/08/18 23:52

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

2021/08/19 02:07

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

2021/08/19 02:19

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

2021/08/19 05:07

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

2021/08/19 08:12

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

2021/08/19 08:20

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

2021/08/19 12:52

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

2021/08/19 20:12

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

2021/08/20 02:43

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

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

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

date

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

JSON

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

Swift

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