【Swift】Codableで後からキーを追加した場合の挙動

公開日: : iOSアプリ開発

こんにちは、@akio0911です。

SwiftのCodableで後からキーを追加した場合の挙動についてメモっておこうと思います。

旧バージョンでJSONを出力する

まずはnameプロパティだけを持つPersonというstructを作り、そのインスタンスをJSON形式にエンコードしてみます。

struct Person: Codable {
	let name: String
}

do {
	let person = Person(name: "akio")
	let data = try JSONEncoder().encode(person)
	let json = String(data: data, encoding: .utf8)!
	print(json)
} catch {
	print(error.localizedDescription)
}

実行結果は以下のようになります。

{"name":"akio"}

新バージョンでデコードしてみる(非オプショナル)

Personにプロパティage(非オプショナルのInt)を追加し、先ほどエンコードしたJSONを読み込んでみます。

struct Person: Codable {
	let name: String
	let age: Int
}

do {
	let json = """
{"name": "akio"}
"""
	let data = json.data(using: .utf8)!
	let person = try JSONDecoder().decode(Person.self, from: data)
	print(person)
} catch {
	print(error.localizedDescription)
}

実行結果は以下の通り。JSONの中にageというキーが無いため、エラーとなっています。

The data couldn’t be read because it is missing.

新バージョンでデコードしてみる(オプショナル)

PersonのプロパティageをオプショナルのIntに変更し、先ほどと同じJSONを読み込んでみます。

struct Person: Codable {
	let name: String
	let age: Int?
}

do {
	let json = """
{"name": "akio"}
"""
	let data = json.data(using: .utf8)!
	let person = try JSONDecoder().decode(Person.self, from: data)
	print(person)
} catch {
	print(error.localizedDescription)
}

実行結果は以下の通り。今回はエラーになりませんでしたが、ageの値はnilとなっています。

Person(name: "akio", age: nil)

まとめ

Codableに適合している型に後から新たなプロパティを追加した場合、デコード対象のJSONに対応するキーが存在しなかった時に、

  • 追加したプロパティが非オプショナルだった場合、エラーとなる
  • 追加したプロパティがオプショナルだった場合、対応する値はnilとしてデコードされる

という挙動になりました。

この記事を書いた人
あきお(@akio0911
iOSエンジニア、ブロガー。「プログラミングで人々を幸せに」をテーマに活動中。著書に「iPhoneアプリ開発レシピ」「cocos2d for iPhoneレッスンノート」など。東京・大阪にてアプリ開発講座「アプリクリエイター道場」を主催。 MAMORIO株式会社 技術顧問(インタビュー記事)、VISITS Technologies株式会社 技術顧問(インタビュー記事)。ブログ「卵は世界である」を運営。

関連記事

この記事が気に入ったら「いいね!」しよう

follow us in feedly

Feedlyで最新記事を購読

Twitterで更新情報をゲット!

LINEでご感想・ご要望お送りください!
(スマホでLINEを起動 > 友だち追加 > QRコード)

プログラミング未経験者向けのプログラミング入門連載記事を始めます

こんにちは、@akio0911です。 これからプログラミング未経

【RxSwift】BehaviorRelayとPublishRelayについてまとめてみた

こんにちは、@akio0911です。今回はRxSwiftのBe

【RxSwift】materialize, dematealizeを使ってみた

@toshi0383さんに教えていただいた、RxSwiftのm

【RxSwift】ストリームのcompletedをつぶす(消し去る)方法

RxSwiftで元々のストリームからcompletedをつぶす

【RxSwift】completedかerrorが流れてきたらsubscribeはdisposeされる

RxSwiftにおいて、completedかerrorが流れて

→もっと見る

PAGE TOP ↑