SwiftUI JSON文字列をJSONDecoderで構造化する。

SwiftUIで、Stringに入っているJSONを処理する場合JSONDecoderで構造体にdecodeして利用します。Swiftコード内に下記のJSON文字列を用意します。

let timeTraveller_json:String = """
	{ "morlock" :
		{"Eloi":"🦄 Weena 🌸"
	}
"""

上のJSON文字列と同じような構造体を作成します。

struct TTimeTraveller : Decodable {
    struct TMorlock : Decodable {
        var Eloi: String?
    }
    var morlock : TMorlock
}

構造体の派生元はDecodableにする必要があるようでした。この例ではTMorlockTTimeTravellerの中に書きましたが分けても問題ないようです。

Viewを作成し、Button アクションの中に「“Eloi”:”🦄 Weena 🌸”」を呼び出せるようにし、Text表示させます。

struct StringJSON: View {
    let timeTraveller_json:String = """
        { "morlock" :
            {"Eloi":"🦄 Weena 🌸", "JapaneseName": "ウィーナ"}
        }
    """
    @State var s1: String = ""
    var body: some View {
        VStack{
            Text(self.s1)
            Button("Button1", action: {
                do {
                    let model1 = try JSONDecoder().decode(TTimeTraveller.self, from: self.timeTraveller_json.data(using: .utf8)! )
                    self.s1 = model1.morlock.Eloi!
                } catch { }
            })
            Spacer()
        }
    }
}

JSON文字列に「“JapaneseName”: “ウィーナ”」を追加しました。使わなければ問題ありません。その反対の構造体側に余計な項目があっても使わない場合エラーにはなりませんでした。

struct TMorlock : Decodable {
    var Eloi: String?
    var JapaneseName: String?
}

TMorlockJapaneseNameを追加すればその項目も利用できます。

JSON文字列を構造体にdecode
JSON文字列を構造体にdecode

SwiftUI Webサーバーから文字列取得する getHTTP

SwiftUIでボタンを押すとWebサーバーから文字列を取得する方法。

ObservableObjectを継承したクラスを作成する。

class TNetHTTPClient:ObservableObject {
    @Published var responseString: String
    init() {
        self.responseString = ""
    }
    func get(aurl: String) -> Void {
        guard let url1 = URL(string: aurl) else { return }
        URLSession.shared.dataTask(with: url1) { (data, res, _) in
            guard let data = data else { return }
            DispatchQueue.main.async {
                print(res ?? "")
                if let res = res as? HTTPURLResponse {
                    if res.statusCode == 200 {
                        self.responseString = " \( String(data: data, encoding: .utf8) ?? "" ) "
                    } else {
                        self.responseString = "status code = \(res.statusCode)"
                    }
                }
            }
        }.resume()
    }
}

Viewの構造体を作成しWebサーバーに接続するためのButtonと、HTTPレスポンスした文字列表示するためのTextFieldを配置します。

struct GetHttp: View {
    let http_url: String = "https://mjeld.com/moji.txt"
    @ObservedObject var netHTTPClient1 = TNetHTTPClient()
    var body: some View {
        VStack{
            Text("Get a string from the server.")
            TextField(self.http_url, text: self.$netHTTPClient1.responseString)
                .padding(.horizontal)
            HStack{
                Button("Button1", action: {
                    self.netHTTPClient1.get(aurl: self.http_url)
                })
                Button("Button2", action: {
                    self.netHTTPClient1.responseString = ""
                })
            }
            Spacer()
        }
    }
}

@ObservedObjectで先に作っていたクラスTNetHTTPClientを宣言します。TextFieldのtextは$netHTTPClient1.responseStringを設定しresponseStringが変更した場合TextFieldに反映されます。Button1をタップするとnetHTTPClient1.get(aurl: self.http_url)が実行されます。

URLからデータを取得しTextFieldに表示する
URLからデータを取得しTextFieldに表示する

実行し、Buttonを押すと上のようにWebサーバーの文字列を取得します。Webサーバー側にはUTF8のプレーンテキストファイルを置いています。

https://developer.apple.com/documentation/foundation/urlsession/1411554-datatask

2022 MJELD TECHNOLOGIES. ALL RIGHTS RESERVED