[Swift3] JSON文字列の作成
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 最後に
ちょっと慣れてきたでしょうか。(と自分に言い聞かせています)