こんにちは!文系出身、独学で個人開発をしている「ゆとりくん」です????
当サイトでは自分が過去に躓いた内容を中心に、アプリ開発初心者の方に有益な情報を紹介しています。
今回のテーマは「JSONSerializationクラスって、どう使うの?」です。
初心者の方が理解しやすいようになるべく優しい言葉でまとめましたので、ぜひ参考にしてみてください!
※本記事は、著者が学習した内容をまとめたものとなります。
内容の精査につきましては、執筆時の技術力で可能な限りの注意を払っていますが、万が一誤りがございましたらフォームからご一報いただけると幸いです。
この記事はこんな方におすすめ!
- JSONのデータをSwiftで扱えるようにしたい!
- JSONSerializationクラスの基本的な使い方を知りたい!
自分が躓いた点を中心に、初心者の方に向けて記事を書いています!
環境
この記事は以下のバージョン時点での情報をまとめています。
【XCode】15.3
【Swift】5.10
【iOS】17.1.2
【macOS】Sonoma 14.2
JSONSerializationクラスとは
JSONSerializationクラスとは、JSON形式のデータと、Swiftの標準的なデータ型(Dictionary型など)とを、相互に変換するためのクラスです。
そもそもJSONってなに?
JSONは、データの記述形式の1種です。
データ形式として有名なものはCSVやXMLなどがありますが、JSONはもともとJavaScriptでデータ通信を行う際のフォーマットとして開発されたようです。
たとえば、「Apple製品」を表すJSONは以下のように記述されます。
[
{
"id" : "0001",
"name" : "iPhone",
"price" : 100000
},
{
"id" : "0002",
"name" : "iPad",
"price" : 60000
}
{
"id" : "0003",
"name" : "iMac",
"price" : 140000
}
]
JavaScriptの文法が分からなくても「idと名前と値段が記載されたAppleの製品が3つ並べられているな〜」ということがなんとなく推測できますね!
上記のJSONを、Swiftの辞書型を用いて表現すると以下のようになります。
let products: [[String : Any]] = [
[
"id": "0001",
"name": "iPhone",
"price": 100000
],
[
"id": "0002",
"name": "iPad",
"price": 60000
],
[
"id": "0003",
"name": "iMac",
"price": 140000
]
]
キーをString型・バリューをAny型とした辞書型のオブジェクトを3つ、配列に格納しました。
こうすることで、JSONと同じ内容のデータをSwiftでも扱うことができます。
しかし、データの数が10個・100個・1000個と増えた場合、上記のように手動で変換を行うにはとても手間がかかってしまいます。
そこでJSON⇆Swift間のデータ変換を簡単に行える、JSONSerializationクラスの出番というわけです✨
JSONSerializationは、あくまでもJSONをSwiftのFoundationフレームワークの型(Dictionary, Arrayなど)へ変換するために用いられます。
JSONとSwiftのカスタムクラス間で変換を行いたい場合には、Codable, Decodable, Encodableなどの方法を利用します。
JSONSerializationクラスの使い方
概要が掴めたところで、さっそく具体的な使い方を見ていきましょう。
Swiftの型(Dictionary)から、JSONへ変換する方法
まずは、SwiftのDictionary型をJSONへ変換する方法です。
先ほども例として挙げた、[[String : Any]]型の定数productsを、JSONに変換していきます。
//これをJSON形式に変換する
let products: [[String : Any]] = [
[
"id": "0001",
"name": "iPhone",
"price": 100000
],
[
"id": "0002",
"name": "iPad",
"price": 60000
],
[
"id": "0003",
"name": "iMac",
"price": 140000
]
]
JSONSerializationクラスのdata(withJSONObject:options:)メソッドを利用して、JSONへの変換を行います。
let jsonData = try? JSONSerialization.data(withJSONObject: products)
JSONへの変換自体は、なんとこの1行で完了です。
data(withJSONObject:options:)メソッドのポイントは以下の3点です。
- 引数optionsには、初期値として空の配列が設定されるため省略可能
- dataメソッドはクラスメソッドなので、JSONSerializationクラスをインスタンス化することなく利用することができる
- dataメソッドはエラーをスローする可能性があるので、try?を付与して呼び出す
では、本当にJSONへの変換ができているのか確認してみましょう。
STEP1で作成した定数jsonDataを、オプショナルバインディングを用いてアンラップし、printで表示してみます。
STEP1で記述したコードを、以下のように変更してみてください。
//if-let文を利用して、アンラップする
if let jsonData = try? JSONSerialization.data(withJSONObject: products){
print(jsonData)
}
実行すると、以下のように出力されます。
131 bytes
データの内容ではなく、データサイズが表示されていしまいました。
data(withJSONObject:options:)メソッドは、Data?型を返します。
アンラップして得られたData型を直接print関数に渡すと、データのサイズがバイト数で表示されてしまいます。
データの中身を確認したい場合、それに適した形に変更する必要があります。
参考: Data型とは?
It’s designed to store any kind of data you can think of, such as strings, images, zip files, and more.
Paul Hudson. Hacking with iOS(SwiftUI Edition). Hacking with Swift. 2024. p230
(これは文字列、画像、zipファイルなど、考えられるあらゆる種類のデータを保存するために設計されています。)
Data型の中身を文字列として表示するには、String型のイニシャライザinit(data:encoding:)を利用します。
STEP2のコードを以下のように変更してみてください。
if let jsonData = try? JSONSerialization.data(withJSONObject: products){
//表示可能な形式に変更する
if let jsonDataForDisplay = String(data: jsonData, encoding: .utf8){
//データを出力する
print(jsonDataForDisplay)
}
}
String型のイニシャライザ、init(data:encoding:)は失敗可能イニシャライザなので、nilを返す可能性があります。そのため、if-let文でアンラップを行います。
上記のコードを実行すると、以下のように出力されます。
[{"name":"iPhone","id":"0001","price":100000},{"id":"0002","name":"iPad","price":60000},{"id":"0003","price":140000,"name":"iMac"}]
確かに、JSONに変換できていることが確認できました!
JSONをSwiftの型(Dictionary型)に変換する方法
続いて、さきほど作成したJSONのデータをSwiftで利用可能な元の形([[String: Any]]型)に戻してみましょう。
JSONSerializationクラスのjsonObject(with:options:)メソッドを利用して変換を行います。
このメソッドはAny型を返します。
//変換元のJSONデータ
if let jsonData = try? JSONSerialization.data(withJSONObject: products){
//JSONをSwiftで利用可能な型に変換する
if let swiftData = try? JSONSerialization.jsonObject(with: jsonData){
//定数swiftDataはAny型
//追加の処理をSTEP2で記述する
}
}
ダウンキャストを用いてAny型を[[String: Any]]型に変換します。その後、結果を出力します。
if let jsonData = try? JSONSerialization.data(withJSONObject: products){
//JSONをSwiftで利用可能な型に変更する
if let swiftData = try? JSONSerialization.jsonObject(with: jsonData){
//Any型を[[String : Any]]型にダウンキャストし、表示する
if let swiftDataForDisplay = swiftData as? [[String : Any]]{
print(swiftDataForDisplay)
}
}
}
上記のコードを実行すると、以下のように出力されます。
[["id": 0001, "name": iPhone, "price": 100000], ["name": iPad, "price": 60000, "id": 0002], ["name": iMac, "id": 0003, "price": 140000]]
無事に元の形に戻すことができました!
まとめ
- SwiftのデータをJSONに変換するには、JSONSerializationクラスのdataメソッドを利用する
- JSONをSwiftのデータに変換するには、JSONSerializationクラスのjsonObjectメソッドを利用する
- JSONSerializationクラスは、Swiftの基本的なクラス(DictionaryやArrayなど)とJSON間の変換に用いる(カスタムクラスへの変更には使わない)
以上、参考になれば嬉しいです!
まだまだ勉強中ですので、間違い等ありましたらフォームよりご連絡ください????????
参考資料
- 生形可奈子. スラスラわかるJavaScript. 翔泳社, 2019, p325~P328
- 山田祥寛. 改定新版 JavaScript 本格入門~モダンスタイルによる基礎から現場の応用まで~. 技術評論社, 2020, p174
- Swiftful Thinking. “Codable, Decodable, and Encodable in Swift | Continued Learning #21”. Youtube. 2021-04, (参照 2024-04-21)
- Paul Hudson. Hacking with iOS(SwiftUI Edition). Hacking with Swift. 2024.
- Apple. “JSONSerialization”. AppleDeveloper, (参照 2024-04-21)
- Apple. “data(withJSONObject:options:)”. AppleDeveloper, (参照 2024-04-21)
- Apple. “jsonObject(with:options:)”. AppleDeveloper, (参照 2024-04-21)
- Apple. “init(data:encoding:)”. AppleDeveloper, (参照 2024-04-21)
コメント