この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
今回は、JSON文字列をSwiftで作成する要領について纏めてみました。
本記事は、例えば、「APIで下記のようなJSONデータとしてPOSTしたい!」というような場合に、プログラムで、このJSON文字列を生成する事になりますが、「う、どうだっけ・・・」とちょっと固まりそうな方(私のことです)に向けたものです。
{
"Identifire": "123456",
"Code": "AAA-ZZZ",
"LastUpdate": "2017-04-01T09:30:00.000Z",
"Tags": [
{
"Value": "Taro",
"Key": "Name"
},
{
"Value": 23,
"Key": "Age"
}
]
}
なお、JSONについては、下記がとっても優しく分かりやすかったので、超おすすめです。
非エンジニアに贈る「具体例でさらっと学ぶJSON」
2 JSONSerialization
Swiftでは、Foundationのオブジェクトで表現された データをJSONSerializationでJSONオブジェクト(Data)に変換し、更にStringに変換することでJSON文字列を生成することができます。
let jsonObj = ["Name":"Taro"]
do {
let jsonData = try JSONSerialization.data(withJSONObject: jsonObj, options: [])
let jsonStr = String(bytes: jsonData, encoding: .utf8)!
print(jsonStr) // 生成されたJSON文字列 => {"Name":"Taro"}
} catch let error {
print(error)
}
JSONSerializationを使用した変換は、定形作業なので、問題は、各種のJSONをFoundationオブジェクトで表現するところだと思います。
3 Dictionary
最初に、最も簡単(?)なJSON文字列を生成してみます。
{
"Name":"Taro"
}
Swiftでのコードは、次のようになります。
let jsonObj = ["Name":"Taro"]
動的に作成するなら、下記のようになるでしょうか。
var jsonObj = Dictionary<String,Any>()
jsonObj["Name"] = "Taro"
JSONにおけるオブジェクト型データ(Key、Value)は、Foundationでは、Dictionaryで表現します。キーは、String 一択ですが、値の方は、色々考えられますので、Anyとしています。(例えば、全部の値が文字列であるならDictionary<String,String>のように定義することも可能です)
var jsonObj = Dictionary<String,Any>()
jsonObj["Name"] = "Taro"
jsonObj["Age"] = 23 // Anyなので数値も入ります
/*
{
"Name":"Taro",
"Age":23
}
*/
4 Array
複数の要素を保持するものには、先のDictionaryの他に、Arrayがあります。
let jsonObj: [Any] = ["Name",123]
/*
[
"Name",
123
]
*/
同じく動的に生成するなら、次のようになります。
var jsonObj = Array<Any>()
jsonObj.append("Name")
jsonObj.append(123)
/*
[
"Name",
123
]
*/
Arrayに含まれる要素は、一種類でない場合、Anyとするしか無いでしょう。
5 階層構造
複数の要素を保持できるDictionaryや、Arrayを値として指定した場合、階層構造を築くことになります。
下記は、Arrayの要素に、Dictionaryを設定している例です。
var jsonObj = Array<Any>()
jsonObj.append(["Name":"Taro"])
jsonObj.append(["Name":"Hanako"])
/*
[
{
"Name": "Taro"
},
{
"Name": "Hanako"
}
]
*/
さて、それでは、次のようなJSONは、プログラムで生成する場合、どうやって作業を進めれば良いのでしょう?
{
"person": {
"Age": 23,
"Name": "Taro"
}
}
最初にトップレベルの型ですが、全体が、{ } で囲まれているので、トップレベルはDictionaryであると言えます。( [ ] の場合は、Arrayです)
そして、その1つ目の要素(上の例では、要素は1つしかありません)は、キーが "person" で、値 が「 ”{ Dictionary }” 」です。
こういう場合は、最初に personを作成します。
var person = Dictionary<String,Any>()
person["Name"] = "Taro"
person["Age"] = 23
そして、このpersonをトップレベルのオブジェクトの要素として追加します。
var jsonObj = Dictionary<String,Any>()
jsonObj["person"] = person
どんなに、階層構造になっていても、一番下のオブジェクトから順に生成して、上の要素に追加して行けばOKです。
6 練習
それでは、最初に例として紹介したJSON文字列を、Swiftで書いてみます。
眺めてみると・・・まず、トップオブジェクトはDictionaryです。 その要素は4つであり、最後の要素の値は、Arrayのようです。 また、Arrayの要素は2つであり、それぞれDictionaryです。
{
"Identifire": "123456",
"Code": "AAA-ZZZ",
"LastUpdate": "2017-04-01T09:30:00.000Z",
"Tags": [
{
"Value": "Taro",
"Key": "Name"
},
{
"Value": 23,
"Key": "Age"
}
]
}
コードは、以下のとおりです。
// Dictionary(Tags配列の要素)を生成する
var name = Dictionary<String, String>() // var name = Dictionary<String, Any>() でもよい
name["Key"] = "Name"
name["Value"] = "Taro"
// Dictionary(Tags配列の要素)を生成する
var age = Dictionary<String, Any>()
age["Key"] = "Age"
age["Value"] = 23
// Tags配列の生成
var tags = Array<Any>() // var tags = Array<Dictionary<String, Any>>() でもよい
// Tags配列へ要素を追加する
tags.append(name)
tags.append(age)
// トップオブジェクトの生成
var jsonObj = Dictionary<String, Any>()
// トップオブジェクトへ要素を追加する
jsonObj["Identifire"] = "123456"
jsonObj["Code"] = "AAA-ZZZ"
jsonObj["LastUpdate"] = "2017-04-01T09:30:00.000Z"
jsonObj["Tags"] = tags
7 最後に
ちょっと慣れてきたでしょうか。(と自分に言い聞かせています)