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

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

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

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

解決済

1回答

1017閲覧

API通信で返ってきたjsonデータを上手くデコードできない

otomodayo

総合スコア10

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

0クリップ

投稿2020/09/29 04:31

現在、Codableを使用して、API通信で返ってきたjsonデータを処理しております。
structクラスは以下のような形です。

Swift

1struct User: Codable { 2 var user_id: Int = 0 3 var name: String = "" 4 var age: Int = 0 5}

困っていること

user_idとnameはちゃんとデコードできるのですが、
ageに対して返ってくるデータの型が定まっておらず(String型だったりInt型だったり)
上手くデコードすることができません。

Codableは型を指定しないとダメとのことだったのですが、
この場合、どのようにすれば可変の型に対応することができるでしょうか。
※都合上、jsonで返ってくる値の型を統一することができません。

どなたか、分かる方がいらっしゃいましたら、
ご回答いただけますと幸いです。

よろしくお願いいたします。

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

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

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

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

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

TsukubaDepot

2020/09/29 07:17

age として返ってくるデータのパターンは限定されるのでしょうか。 数値が数値として渡されるのか、数字の文字列(ダブルクオートで括られる)なのか、それとも数値や符号とは一切関係ないデータも含まれるのか、によって対策が変わってくるのかと思います。 できれば、「こういうパターンがありうる」という例をご質問本文に記載された方が回答もつきやすのかもしれません。
otomodayo

2020/09/29 10:25

質問ありがとうございます。 また、アドバイスもありがとうございます。大変参考になります。 ありうるパターンとしては以下です。 ・数値 ・数字の文字列 数字以外の文字が入ることはありません。
guest

回答1

0

ベストアンサー

改良の余地は十分になるとおもいますし、もっと良い指摘も入るかと思いますが、こんな感じでいかがでしょうか。

上記の記事にはお世話になっていますし、今回も参考にしました。

Swift

1import UIKit 2 3let data = """ 4[ 5{ 6 "model": "iPhone X", 7 "capacity": "64" 8}, 9{ 10 "model": "iPhone 7", 11 "capacity": 128 12}, 13{ 14 "model": "iPhone 6", 15 "capacity": -128 16}, 17{ 18 "model": "iPhone 5", 19 "capacity": "-128" 20} 21] 22""".data(using: .utf8)! 23 24 25struct Device: Codable { 26 var model: String 27 var capacity: Int 28 29 private enum CodingKeys: String, CodingKey { 30 case model 31 case capacity 32 } 33 34 init(from decoder: Decoder) throws { 35 let values = try decoder.container(keyedBy: CodingKeys.self) 36 model = try values.decode(String.self, forKey: .model) 37 if let cap = try? values.decode(Int.self, forKey: .capacity) { 38 capacity = cap 39 } else { 40 capacity = Int(try values.decode(String.self, forKey: .capacity)) ?? 0 41 } 42 } 43 44 func encode(to encoder: Encoder) throws { 45 var container = encoder.container(keyedBy: CodingKeys.self) 46 try container.encode(model, forKey: .model) 47 try container.encode(capacity.description, forKey: .capacity) 48 } 49} 50 51 52if let device = try? JSONDecoder().decode([Device].self, from: data) { 53 device.forEach { dev in print("モデル: (dev.model)\nメモリ: (dev.capacity)") } 54} 55// 実行結果 56//モデル: iPhone X 57//メモリ: 64 58//モデル: iPhone 7 59//メモリ: 128 60//モデル: iPhone 6 61//メモリ: -128 62//モデル: iPhone 5 63//メモリ: -128

投稿2020/09/29 10:51

TsukubaDepot

総合スコア5086

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

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

otomodayo

2020/10/01 23:29

丁寧にご回答いただき、ありがとうございます。 こちらで解決できました! このように書くこと、恥ずかしながら存じ上げていませんでした・・・ もっとちゃんと勉強しようと思います。 大変助かりました。 本当にありがとうございます!
TsukubaDepot

2020/10/02 07:35

私こそちゃんと書ける訳ではないので、こういうお題があると大変勉強になります(正解かわかりませんが)。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.39%

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

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

質問する

関連した質問