JSONDecoder/Encoder
Swift4から使えるようになったと噂のJSONDecoder/Encoderを使ってみました。StringとDataの変換があるせいでややこしく見えますが、decoder.decode
とencoder.encode
を使ってシンプルにデコード/エンコードができます。
// json = [["a":"1"],["b":"2"]]
let json = "[{\"a\":\"1\"},{\"b\":\"2\"}]".data(using: .utf8)!
let decoder = JSONDecoder()
let objs = try decoder.decode([[String:String]].self, from: json)
オブジェクト(Dictiynaryの配列,objs)を再びJSON(文字列)にします。
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(objs)
print(String(data: data, encoding: .utf8)!)
.prettyPrinted
を指定すると以下のように整形されて出力されます。
[
{
"a" : "1"
},
{
"b" : "2"
}
]
デコードの際に、取得するオブジェクトの型を指定する必要があります。そのため、構造が予めきちんと定義されている(把握できている)JSONでないと扱いが難しくなります(デコーダのカスタムを駆使すれば不可能ではなさそうですが…)。
JSONSerialization
型がバラバラのJSONを扱う場合は、JSONSerializationの方がお手軽です。その代わり、細かくデータの整合性を確認していくのは大変ですが…。(下記例では強引に「as!」でキャストしていますが、実際にはもう少し丁寧にエラー処理をする必要があると思われます)
let json = "[{\"a\":\"str\"},{\"b\":2}]".data(using: .utf8)!
let o = try JSONSerialization.jsonObject(with: json)
let objs = o as! [[String:Any]]
let data = try JSONSerialization.data(withJSONObject: objs, options: .prettyPrinted)
print(String(data: data, encoding: String.Encoding.utf8) ?? "can't encode")
JSONSerializationについては下記の記事でも触れています。
https://qiita.com/lumbermill/items/6cd1c92909e7ae11a517