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

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

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

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

Swift

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

Q&A

解決済

1回答

2023閲覧

SwiftでJSONをURLから取得しLabelに流し込みたい

mitdok

総合スコア49

JSON

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

Swift

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

0グッド

0クリップ

投稿2020/11/10 07:41

試行錯誤の上、たどり着いたのは以下のコードです。

Swift

1 struct Record:Codable { 2 let shindo : String 3 let equrl : String 4 } 5 let url = URL(string: "https://dokasen.com/eqimg/new.json")! //URLを生成 6 let request = URLRequest(url: url) //Requestを生成 7 let task = URLSession.shared.dataTask(with: request) { (data, response, error) in //非同期で通信を行う 8 guard let data = data else { return } 9 do { 10 11 let object = try JSONSerialization.jsonObject(with: data, options: []) // DataをJsonに変換 12 print(object) 13 14 guard let jsonData = try? JSONDecoder().decode(Record.self, from: object as! Data) else { 15 print("json変換に失敗しました") 16 return 17 } 18 print(jsonData.shindo) 19 self.label.text = jsonData.shindo 20 21 } catch let error { 22 print(error) 23 } 24 } 25 task.resume()

このコードでビルドできるのですが、エミュレータがクラッシュして動作しません。
直すべき箇所や、他にいい方法があればご教示ください。
参考になるURLでも何でもいいです。
よろしくおねがいします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

ご提示のコードだと確かにコンパイルは通るかもしれませんが、強制的なキャストなどを行ったり、try? にしてしまうことでエラーハンドリングが適切に行われないため、容易に発見できるミスも発見できなくなってしまっています。

ミスですが、

  1. 構造体 Record のプロパティ名が JSON のキー名と一致していない
  2. Data 型で渡されてきたデータを不必要に JSON オブジェクトにしている。
  3. また、JSON オブジェクトになった型(__NSDictionary)を Data に強制キャストしているため、実行時エラーで落ちている
  4. UILabel の書き換えはメインスレッドで行わなければならないが、離脱するクロージャ内で行っているため、ここも実行時エラーで落ちる要因となっている。

といった具合です。

大きな修正は必要ないですが、ご提示いただいている部分だけで修正したものは次の通りとなります。

Swift

1struct Record:Codable { 2 let shindo : String 3 // MARK: JSON のキー名と一致していないのでエラーが出る 4 //let equrl : String 5 let urleq : String 6} 7 8let url = URL(string: "https://dokasen.com/eqimg/new.json")! //URLを生成 9let request = URLRequest(url: url) //Requestを生成 10let task = URLSession.shared.dataTask(with: request) { (data, response, error) in //非同期で通信を行う 11 guard let data = data else { return } 12 do { 13 // MARK: URLSession に渡すクロージャのうち、data は既に Data 型になっているので下記の作業は不要 14 // let object = try JSONSerialization.jsonObject(with: data, options: []) // DataをJsonに変換 15 // print(object) 16 // 17 18 // MARK: from の部分には直接 data を渡す。また、try? にするとエラーハンドリングできなくなるので、try で実行する。 19 // guard let jsonData = try? JSONDecoder().decode(Record.self, from: object as! Data) else { 20 21 let jsonData = try JSONDecoder().decode(Record.self, from: data) 22 23 print(jsonData.shindo) 24 25 // MARK: UIパーツに値を渡すときにはメインスレッドで実行させる 26 DispatchQueue.main.async { 27 self.label.text = jsonData.shindo 28 } 29 30 } catch let error { 31 print(error) 32 } 33} 34task.resume()

投稿2020/11/10 11:53

TsukubaDepot

総合スコア5086

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

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

mitdok

2020/11/10 14:11

修正頂いたもので試したところ、無事動きました。 ミスの部分まで丁寧に解説して頂いて、勉強になりました。 確かにJSONで届いてるはずのデータを謎にJSONにしてる箇所あったり・・・。 本当に、本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問