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

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

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

キャストとは、オブジェクトの型の変換が許可された場合に、明白に別の型への変換を行うプロセスのことです。

Swift

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

Q&A

解決済

2回答

352閲覧

Alamofireにおけるダウンキャストについて

mememehollow

総合スコア6

キャスト

キャストとは、オブジェクトの型の変換が許可された場合に、明白に別の型への変換を行うプロセスのことです。

Swift

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

0グッド

0クリップ

投稿2020/04/19 04:30

###この質問に至った経緯
Alamofireのコード部分で使われるダウンキャストがどのような意味をなしてるか知りたかったためです。

###問題点
以下のサイトでSwiftの通信フレームワークであるAlamofireについて学んでいました。

https://medium.com/better-programming/combine-swiftui-with-alamofire-abb4cd4a0aca

そして、Alamofireが使われているコード部分は以下のようになっています。

Swift

1class Observer : ObservableObject{ 2 @Published var jokes = [JokesData]() 3 4 init() { 5 getJokes() 6 } 7 8 func getJokes(count: Int = 5) 9 { 10 Alamofire.request("http://api.icndb.com/jokes/random/(count)") 11 .responseJSON{ 12 response in 13 if let json = response.result.value { 14 if (json as? [String : AnyObject]) != nil{ 15 if let dictionaryArray = json as? Dictionary<String, AnyObject?> { 16 let jsonArray = dictionaryArray["value"] 17 18 if let jsonArray = jsonArray as? Array<Dictionary<String, AnyObject?>>{ 19 for i in 0..<jsonArray.count{ 20 let json = jsonArray[i] 21 if let id = json["id"] as? Int, let jokeString = json["joke"] as? String{ 22 self.jokes.append(JokesData(id: id, joke: jokeString)) 23 } 24 } 25 } 26 } 27 } 28 } 29 } 30 } 31}

実際にこのコードがどういう物なのか解析している途中で、なぜ、このようなダウンキャストが多くみられるか、知りたくなったので、質問しました。このようなダウンキャスト達がなぜ出てくるのかをわからないので知りたいです。どうかよろしくお願いします。

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

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

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

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

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

guest

回答2

0

例えば以下のようなJSONデータがあるとします。

JSON

1 2{ "name" : "Hoge Foo", 3 "price" : 199, 4 "soldout" : false, 5 "address" : { "country" : "Japan", 6 "city" : "Shibuya", 7 "state" : "Tokyo" } 8}

この場合、JSONのキー名に対応する型が文字列だったり数値だったりBooleanだったり他のDictionaryだったりします。
なのでこの時点では[String : AnyObject]としてしか表現できません。
以下のように判別できるレベルまでDictionaryから取り出してCastしてあげる必要があります。

Swift

1let name = jsonData["name"] as? String 2let price= jsonData["price"] as? Int 3let soldout= jsonData["soldout"] as? Bool 4let address= jsonData["address"] as? [String:String] 5

また、SiwftではCodableという仕組みがあり、この手のCast処理を自動でやってくれます。

投稿2020/04/19 09:24

nakasho_dev

総合スコア2655

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

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

mememehollow

2020/04/24 02:33

お礼が遅くなってしまい申し訳ありません。 わかりやすく教えていただいて本当にありがとうございました!
guest

0

ベストアンサー

JSONの概念と、このサンプルで取得できるJSONの形式はご理解されているという前提でコメントします。

swift

1if let json = response.value { 2 // json がキーをString型、値がAnyObject型を値とする辞書(Dictionary型)かチェックするためのダウンキャスト 3 // この行が本当に必要なのかはちょっと自信がない。次の行のif-let(オプショナルバインディング)でも良いと思う。 4 if (json as? [String : AnyObject]) != nil{ 5 // ここではキーをString型、値がAnyObject型を値とする辞書(Dictionary型)かチェックするためのダウンキャストを行う。 6 if let dictionaryArray = json as? Dictionary<String, AnyObject?> { 7 // 辞書からキー名が"value"の値だけ抜き出す。 8 let jsonArray = dictionaryArray["value"] 9 // "value"で抜き出した JSON の要素が、今度はキーがString型、値がAnyObject型の配列かチェック。 10 // 値は Int と String が混在しているので、ここではAnyObjectとしてチェックする 11 if let jsonArray = jsonArray as? Array<Dictionary<String, AnyObject?>>{ 12 for i in 0..<jsonArray.count{ 13 let json = jsonArray[i] 14 // キーが"id”の要素はInt型なので、Int型としてダウンキャストしてチェック 15 // 同様にキーが"joke"の要素はString型なので、String型としてチェック 16 if let id = json["id"] as? Int, let jokeString = json["joke"] as? String { 17 self.jokes.append(JokesData(id: id, joke: jokeString)) 18 } 19 } 20 } 21 } 22}

オプショナルバインディングで済むところを実質2回やっているところが腑に落ちないのですが、概ね上記のような理由でダウンキャストをやっています。

JSONという形式の特徴上、大枠から見ていくと値の部分に相当するところは様々な形式のデータ型が混在するため、AnyObjectという型として処理する必要があります(nakasho_devさんのご回答も併せてごらんください)。

一方、JSONの細部までデコードが進み、キーに対応付く具体的な型がわかれば、具体的な型として処理しなkればならないため、再度Int型やString型として処理させています。

投稿2020/04/19 09:09

編集2020/04/19 09:29
TsukubaDepot

総合スコア5086

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

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

mememehollow

2020/04/24 02:34

お礼が遅くなって申し訳ありません。 確かにオプショナルバインディングだけでちゃんと動きました! 詳しく教えてくださりありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問