構造体を用意する
JSONに変換するには対応した型が必要なので構造体等でプロパティを宣言する。
1 2 3 4 5 6 7 8 |
// SwiftUIでJSON取得・表示の例 import SwiftUI struct TestCode: Codable, Identifiable { let id = UUID() let title: String let dateTime: String } |
変換コード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
class TestViewModel: ObservableObject { @Published var reports: [TestCode] = [] func fetchReports() { guard let url = URL(string: "https://YOUR_API_ENDPOINT") else { return } URLSession.shared.dataTask(with: url) { data, _, error in guard let data = data, error == nil else { return } if let decoded = try? JSONDecoder().decode([TestCode].self, from: data) { DispatchQueue.main.async { self.reports = decoded } } }.resume() } } struct ContentView: View { @StateObject var viewModel = TestViewModel() var body: some View { List(viewModel.reports) { report in VStack(alignment: .leading) { Text(report.title) Text(report.dateTime) } } .onAppear { viewModel.fetchReports() } } } |
URLSession.shared.dataTask(with: url) { data, response, error in ... }
は、
指定したURLから非同期でデータ(例:JSONや画像など)をダウンロードする処理です。
・data
:ダウンロードしたデータ(例:JSONのバイト列)が入ります。
・response
:サーバーから返ってきた「レスポンス情報」(ステータスコードやヘッダーなど)が入ります。
・error
:通信エラーがあればここに入ります。
・guard let data = data, error == nil else { return }
は、データ取得に失敗した場合は処理を中断(return)します。
このブロック内で、取得したデータをパースして画面に反映するなどの処理を行います。
1 2 3 4 5 |
if let decoded = try? JSONDecoder().decode([TestCode].self, from: data) { DispatchQueue.main.async { self.reports = decoded } } |
各部分の意味
try? JSONDecoder().decode([TestCode].self, from: data)
data
(APIから取得したJSONデータ)を
型の配列(TestCode
[
)にTestCode
]JSONDecoder
を使って「デコード(変換)」します。try?
は失敗した場合にnilを返します(エラーでクラッシュしない)。
if let decoded = ...
- デコードに成功した場合のみ、
decoded
(WeatherReport配列)に値が入ります。 - 失敗した場合は何もせずスキップします。
- デコードに成功した場合のみ、
DispatchQueue.main.async { ... }
- UIの更新は「メインスレッド」で行う必要があるため、
self.reports = decoded
(ViewModelのデータ更新)をメインスレッドで実行します。
まとめ
- APIから取得したJSONデータをSwiftの構造体配列に変換
- 変換に成功したら、UI更新用のデータ(
reports
)にセット - UI更新は必ずメインスレッドで行う
この流れで、APIのデータを画面に反映できるようになります。
継承キーワードについて
各キーワードの詳細。
Codable
- Swiftのプロトコル(規約)です。
Encodable
(エンコード可能)とDecodable
(デコード可能)の両方をまとめたもの。- つまり、JSONなどに変換したり、JSONから構造体に変換したりできるようになります。
Decodable
- Codableのうち「デコード(変換)」専用のプロトコルです。
- 例えばJSONデータ → Swiftの構造体に変換する時に使います。
JSONDecoder().decode(型.self, from: データ)
で利用されます。
Identifiable
- SwiftUIでよく使うプロトコルです。
- 一覧表示(Listなど)で「一意に識別できるid」を持たせるためのもの。
var id: 型
を持っていればOK(例:let id = UUID()
)。- これにより、SwiftUIのListでデータを安全に扱えます。
まとめ
- Codable:エンコード・デコード両方できる
- Decodable:デコード(JSON→構造体)できる
- Identifiable:一意のIDを持ち、SwiftUIのListなどで使える
例
1 2 3 4 5 |
struct WeatherReport: Codable, Identifiable { let id = UUID() // Identifiable用 let title: String // JSONの"title"を受け取る let dateTime: String // JSONの"dateTime"を受け取る } |
このように宣言することで、
・JSONからデータを受け取って構造体に変換できる(Decodable)
・SwiftUIのListで使える(Identifiable)となります。
コメント