Swift で Dictionary を使って JSON からデータを抽出する
前回「Swift で JSON の読み書き」では、struct を定義して、JSON の文字列から struct のオブジェクトに変換する方法をご紹介しました。
ここでは struct を定義せずに、Dictionary を使って Swift で JSON からデータを抽出する方法についてご説明します。
JSON 文字列を Swift の Dictionary へ変換する
今回は JSON の文字列から Swift の Dictionary に変換して、データを取得します。
例として、次のような JSON 文字列から値を抽出します。
これは、CDTFA Tax Rate API というカリフォルニアの税率を取得する API のレスポンスで返ってくる JSON です。
{
"taxRateInfo":[
{
"rate":0.0775,
"jurisdiction":"ANAHEIM",
"city":"ANAHEIM",
"county":"ORANGE",
"tac":"300110370000"
}
],
"geocodeInfo":{
"bufferDistance":50
},
"termsOfUse":"https://www.cdtfa.ca.gov/dataportal/policy.htm",
"disclaimer":"https://www.cdtfa.ca.gov/dataportal/disclaimer.htm"
}
この JSON 文字列から、taxRateInfo の rate と city を取得するには次のようにできます。
import Foundation
let jsonString = """
{
"taxRateInfo":[
{
"rate":0.0775,
"jurisdiction":"ANAHEIM",
"city":"ANAHEIM",
"county":"ORANGE",
"tac":"300110370000"
}
],
"geocodeInfo":{
"bufferDistance":50
},
"termsOfUse":"https://www.cdtfa.ca.gov/dataportal/policy.htm",
"disclaimer":"https://www.cdtfa.ca.gov/dataportal/disclaimer.htm"
}
"""
do {
let jsonDict = try JSONSerialization.jsonObject(with: Data(jsonString.utf8)) as? [String: Any]
let taxRateInfos = jsonDict?["taxRateInfo"] as? [[String: Any]]
if taxRateInfos != nil && taxRateInfos!.count > 0 {
let rate = taxRateInfos![0]["rate"]
let city = taxRateInfos![0]["city"]
print("City: \(city ?? ""), Tax Rate: \(rate ?? "")")
}
} catch {
print("Unexpected error: \(error).")
}
23 行目で JSONSerialization.jsonObject() メソッドを使って、jsonString から、jsonObject に変換し、それをさらに、行目で、[String: Any] 型の Dictionary に変換して jsonDict に代入しています。
24 行目で、jsonDict のキーが taxRateInfo の値を [String: Any] 型の Dictionary の配列に変換して taxRateInfos に代入しています。
taxRateInfos が nil でなく、要素の数が 1 以上の時のみ、ひとつめの要素 (index = 0) のキーが rate と city の値を取得して print しています。
playground で実行すると、結果は次のようになり、city と rate の値が取得できているのがわかります。
このように、抽出したい値まで、JSON の構造に合わせて順番に Dictionary に変換していくことによっても、JSON 文字列から値を抽出することができます。
struct を定義して、まるっとオブジェクトに変換するまでもなく、一部のデータだけ抽出して使いたいような時に便利です。
以上、Swift で Dictionary を使って JSON からデータを抽出する方法についてご説明しました。