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

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

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

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

REST

REST(Representational State Transfer)はwebアプリケーションの構築スタイルの一種です。HTTP GET/POSTによってリクエストを送信し、レスポンスはXMLで返されます。SOAPのようなRPCの構築と比べるとサーバからクライアントを分離することが出来る為、人気です。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

1317閲覧

SwiftUIでRESTAPIからJSONを取得して描画したい

shot110

総合スコア2

JSON

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

REST

REST(Representational State Transfer)はwebアプリケーションの構築スタイルの一種です。HTTP GET/POSTによってリクエストを送信し、レスポンスはXMLで返されます。SOAPのようなRPCの構築と比べるとサーバからクライアントを分離することが出来る為、人気です。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2022/08/24 07:12

編集2022/08/24 07:18

前提

SwiftUIでRESTAPIからJSONを取得して描画する練習コードを書いています。
取得データをJSONにデコードするところでエラーが出て解決できません。
階層構造のあるJSONの処理ができなくて困っています。
SwiftUIに詳しい方ご協力よろしくお願いいたします。

利用中の開発環境
・MacBookPro macOS Monterey Apple M1 Pro
・Xcode 13.4.1

実現したいこと

SwiftUIでRESTAPIから以下のJSONを取得して、
"datetime"と"worker_id"の値を画面に表示したい。

{ "Items": [ { "datetime": "2021-03-01 10:12:14 +0000", "worker_id": "test0001" } ], "Count": 1, "ScannedCount": 1 }

発生している問題・エラーメッセージ

エラー2 Error keyNotFound(CodingKeys(stringValue: "datetime", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"datetime\", intValue: nil) (\"datetime\").", underlyingError: nil))

該当のソースコード

swift

1import SwiftUI 2 3struct Items: Codable { 4 var datetime: String 5 var worker_id: String 6} 7 8struct TestRestApi: View { 9 10/// ここの書き方もよくわかっておらず、テキトーに代入しています 11 @State private var results: Items = Items(datetime: "test1", worker_id: "test2") 12 13 var body: some View { 14 NavigationView { 15 VStack{ 16 Text(results.datetime) 17 Text(results.worker_id) 18 } 19 }.onAppear(perform: loadData) // データ読み込み処理 20 } 21 /// データ読み込み処理 22 func loadData() { 23 24 /// URLの生成 25 guard let url = URL(string: 26 "https://b0lc580z2f.execute-api.ap-northeast-1.amazonaws.com/dev") else { 27 /// 文字列が有効なURLでない場合の処理 28 return 29 } 30 31 /// URLリクエストの生成 32 var request = URLRequest(url: url) 33 34 // POSTを指定 35 request.httpMethod = "POST" 36 37 // content-type を application/json に設定する 38 request.addValue("application/json", forHTTPHeaderField: "content-type") 39 40 // set the request-body(JSON) POSTのテストでポストしているだけ 41 let params: [String: Any] = [ 42 "testNumber": "123567", 43 ] 44 45 do{ 46 request.httpBody = try JSONSerialization.data(withJSONObject: params, options: []) 47 }catch{ 48 print("エラー1") 49 print(error.localizedDescription) 50 } 51 52 /// URLにアクセス 53 URLSession.shared.dataTask(with: request) { data, response, error in 54 55 do { 56 if let items = data { 57 let decodedData = try JSONDecoder().decode(Items.self, from: items) 58 self.results = decodedData 59 } else { 60 print("No data", data as Any) 61 } 62 } catch { 63 print("エラー2") 64 print("Error", error) 65 } 66 67 }.resume() // タスク開始処理(必須) 68 69 } 70} 71 72struct TestRestApi_Previews: PreviewProvider { 73 static var previews: some View { 74 TestRestApi() 75 } 76}

試したこと

struct Items: Codable { var datetime: String var worker_id: String }

ここの定義を色々変えて試しましたが、うまく行きませんでした。

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

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

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

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

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

guest

回答1

0

ベストアンサー

次のような感じはいかがでしょうか。

swift

1import SwiftUI 2 3// ***** JSONに合わせてstructを作ってみました 4struct Items: Codable { 5 var Items: [Item] 6 var Count: Int 7 var ScannedCount: Int 8} 9struct Item: Codable { 10 var datetime: String 11 var worker_id: String 12} 13 14struct TestRestApi: View { 15 16 // ***** Optionalにしてみました 17 @State private var results: Items? 18 19 var body: some View { 20 NavigationView { 21 VStack{ 22 // ***** インデックスが0のものを表示してみました 23 Text(results?.Items[0].datetime ?? "") 24 Text(results?.Items[0].worker_id ?? "") 25 } 26 }.onAppear(perform: loadData) // データ読み込み処理 27 } 28// ...省略...

投稿2022/08/24 14:48

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

shot110

2022/08/25 10:00

ありがとうございます!!希望通りの挙動を確認できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問