用途

サンプルデータサイトFaker API にHTTP通信して、JSONデータをリスト表示します。

https://fakerapi.it/

Faker API については…

実行時の例

「データの取得」をタップすることでREST APIにリクエストし、データ取得します。

image.png

取得したデータをリスト(List)に表示します(表示されているのはサンプルデータです)

image.png

image.png

FakerData は、JOSNデータをstructで定義しています。

FakerModel は、FakerData のリクエストを行い、データを管理するモデルです。

ContentView は、FakerModel を保持し、リスト表示するページです。

//
//  FakerData.swift
//  RestJSONTest01
//
//  Created by Rue on 2024/09/10.
//

// This file was generated from JSON Schema using quicktype, do not modify it directly.
// To parse the JSON, add this file to your project and do:
//
//   let fakerApiData = try? JSONDecoder().decode(FakerApiData.self, from: jsonData)

import SwiftUI

// MARK: - FakerApiData
struct FakerApiData: Codable {
    let status: String
    let code: Int
    let locale, seed: String
    let total: Int
    let data: [FakerData]
}

// MARK: - FakerData
// id を変数に持つ識別できるオブジェクトの指定(Identifiable)
// JSON からデコード、エンコードが可能な指定(Codable)
struct FakerData: Codable, Identifiable {
    let id: Int
    let firstname, lastname, email, phone: String
    let birthday: String
    let gender: Gender
    let address: Address
    let website, image: String
}

// MARK: - Address
struct Address: Codable {
    let id: Int
    let street, streetName, buildingNumber, city: String
    let zipcode, country, countyCode: String
    let latitude, longitude: Double
    
    enum CodingKeys: String, CodingKey {
        case id, street, streetName, buildingNumber, city, zipcode, country
        case countyCode = "county_code"
        case latitude, longitude
    }
}

enum Gender: String, Codable {
    case female = "female"
    case male = "male"
    case other = "other"
}

Faker API のJSONをstructの型定義するには、quicktype を使用しました。

https://app.quicktype.io/

quicktype については…

//
//  FakerModel.swift
//  RestJSONTest01
//
//  Created by Rue on 2024/09/10.
//

import SwiftUI

/// Faker サイトからのサンプルデータを管理するモデル
class FakerModel: ObservableObject {
    /// data の更新情報が送られるように @Published 指定にする。
    @Published var data = [FakerData]()

    init() {
    }
    
    /// res: データ取得後に実行される関数を渡す。@escaping は、非同期で実行されるので、記載する。
    func getData(res: @escaping ([FakerData])->()) {
        // _quantity=30 データを30件取得
        let url = URL(string:"<https://fakerapi.it/api/v2/persons?_locale=ja_JP&_quantity=30&_seed=12456>")!
        // 指定URL にリクエスト
        URLSession.shared.dataTask(with: url) { data, response, error in
            // dara にJSON形式のデータが返ってくるので、FakerApiData 型に変換(デコード)する
            let result = try! JSONDecoder().decode(FakerApiData.self, from: data!)
            // 
            DispatchQueue.main.async {
                // res の関数を実行する。
                res(result.data)
            }
        }.resume()
    }
    
    /// データ取得処理を実行する
    func request() {
        self.getData { data in
            self.data = data
        }
    }
}
//
//  ContentView.swift
//  RestJSONTest01
//
//  Created by Rue on 2024/09/09.
//

import SwiftUI

struct ContentView: View {
    @ObservedObject var fakerModel = FakerModel()
    var body: some View {
        VStack {
            Button("データの取得") {
                fakerModel.request()
            }
            Divider()
            List(fakerModel.data) { item in
                VStack {
                    Text("\\(item.lastname) \\(item.firstname)")
                        .font(.headline)
                    Text("\\(item.address.street)")
                        .font(.subheadline)
                }
            }
        }
        .padding()
    }
}

#Preview {
    ContentView()
}