はじめに
この記事では2つのJSONデコード処理の書き方を説明していきます。
JSONDecoderとJSONSerializationでは処理の書き方などが異なるため
行いたい実装や環境によって適切に選ぶ必要があります。
目次
・JSONDecodeについて
・JSONSerializationについて
・まとめ
「JSONDecoder」について
● 概要
JSONDecoderはSwift 4以降に導入されたクラスで、Codableプロトコルに準拠した型のオブジェクトとJSONデータの相互変換を行います。
JSONDecoderはプロトコルを作成することで、JSONデータから取得した値をSwiftオブジェクトの対応するプロパティに手動で代入する必要がないためJSONSerializationのデコードより安全性の高いコードを書くことができます。
●利用に適しているとき
- Swift 4以降のバージョンの場合
・JSONDecoderはCodableプロトコルに準拠した型を定義することで、型安全性を確保し冗長なデコードコードを削減することができます。
・CodingKeysを使用してプロパティとJSONキーの対応を指定することで、自動的なデコード処理が行われ手動での代入が不要になります。
JSONDecoderのデコード
//jsonのデータ
let jsonString: String = "{\"id\":1, \"name\":\"kansae\"}"
//JSONとの対応関係を指定するためのプロトコル
struct User: Codable {
var identifier: Int
var name: String
//プロパティの値とjsonで取得する値が違う場合CodingKeyを使用して対応させることができる
enum CodingKeys: String, CodingKey {
case identifier = "id"
case name
}
}
if let jsonData = jsonString.data(using: .utf8) {
do {
let user = try JSONDecoder().decode(User.self, from: jsonData)
let name = person.name //直接Stringを入力する必要がないため安全性が高くなる
let age = person.age
} catch {
// デコード失敗した際の処理を書く
}
}
「JSONSerialization」について
※今回はデコードの処理のみの解説になります。
● 概要
JSONSerializationは、Foundationフレームワークに含まれるクラスで、JSONデータのデコード(JSONデータからSwiftオブジェクトの変換)を行います。
JSONSerializationでは配列や辞書型でデコードされるため、データにアクセスする際に値のキーを手動で打つ必要がありヒューマンエラーを引き起こしやすくなります。
●利用に適しているとき
- データ構造がシンプルな場合
・JSONデータが単純で、階層が浅い場合 - 古いiOSバージョンのサポートが必要な場合
・JSONDecodeはSwift 4以降の機能になるため、それ以前のバージョンを使用する場合はJSONSerializationを使用します。
JSONSerializationのデコード
//jsonのデータ
let jsonString: String = "{\"id\":1, \"name\":\"kansae\"}"
if let jsonData = jsonString.data(using: .utf8) {
do {
if let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) as? [String: Any] {
let id = jsonObject["id"] as? Int// ヒューマンエラーを起こしやすい箇所
let name = jsonObject["name"] as? String
}
} catch {
// デコード失敗
// エラーハンドリング
}
}
まとめ
Objective-cからswift5.0にコードを移行する際にJSONDecoderという新しい機能があることを知ったため、今回記事にまとめさせていただきました。
JSONDecoderとJSONSerializationの使い方に迷っている方の参考になればと思います。
また、こうするとより良いなど意見ありましたらコメントお願いします。