0Pricing
Swift Academy · レッスン

キーと日付のデコード戦略

snake_caseや日付のデコード戦略を使用します。

「キーと日付のデコード戦略」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。

デコード戦略の概要

型ごとに CodingKeys 列挙型を記述する代わりに、デコーダーにグローバルな戦略を設定できます。戦略を使うと、すべてのデコード対象の型でキーの変換や日付の解析を一貫して行えます。

import Foundation

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
print("Strategy configured")

convertFromSnakeCase

keyDecodingStrategy = .convertFromSnakeCase を設定すると、first_name のようなキーが firstName というキャメルケースのプロパティに自動的に対応付けられます。CodingKeys は必要ありません。

import Foundation

struct User: Codable {
    var firstName: String
    var lastName: String
}

let json = "{\"first_name\":\"Ada\",\"last_name\":\"Lovelace\"}"
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let u = try decoder.decode(User.self, from: json.data(using: .utf8)!)
print(u.firstName, u.lastName)

Snake Caseへのエンコード

エンコーダーには反対方向のオプションもあります。keyEncodingStrategy = .convertToSnakeCase を設定すると、キャメルケースのプロパティが snake_case のJSONキーとして書き出されます。

import Foundation

struct User: Codable {
    var firstName: String
}

let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
let data = try encoder.encode(User(firstName: "Ada"))
print(String(data: data, encoding: .utf8)!)

すべてのキーに適用される戦略

キー戦略は、ネストされたすべての型のすべてのプロパティに一律に適用されます。API全体で一貫して snake_case が使われている場合に最適です。

import Foundation

struct Meta: Codable { var createdAt: String }
struct Doc: Codable { var docTitle: String; var docMeta: Meta }

let json = "{\"doc_title\":\"A\",\"doc_meta\":{\"created_at\":\"now\"}}"
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let d = try decoder.decode(Doc.self, from: json.data(using: .utf8)!)
print(d.docTitle, d.docMeta.createdAt)

日付の問題

JSONには日付型がありません。Date の値は数値または文字列としてエンコードされるため、デコーダーはその形式を把握する必要があります。dateDecodingStrategy によって、どのように解釈するかを指定します。

import Foundation

struct Event: Codable {
    var name: String
    var date: Date
}

print("Date needs a strategy to parse")

iso8601による日付のデコード

dateDecodingStrategy = .iso8601 を設定すると、2020-01-01T00:00:00Z のような標準ISO-8601タイムスタンプを Date の値に解析できます。

import Foundation

struct Event: Codable {
    var name: String
    var date: Date
}

let json = "{\"name\":\"Launch\",\"date\":\"2020-01-01T00:00:00Z\"}"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let e = try decoder.decode(Event.self, from: json.data(using: .utf8)!)
print(e.date.timeIntervalSince1970)

iso8601による日付のエンコード

エンコーダー側の対応する設定は dateEncodingStrategy = .iso8601 です。これにより、Date の値がISO-8601文字列として書き出されます。

import Foundation

struct Event: Codable {
    var name: String
    var date: Date
}

let e = Event(name: "Launch", date: Date(timeIntervalSince1970: 1577836800))
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
let data = try encoder.encode(e)
print(String(data: data, encoding: .utf8)!)

secondsSince1970戦略

APIがUnixタイムスタンプを数値で送信する場合は、.secondsSince1970 を使ってエポックからの経過秒数として解釈します。

import Foundation

struct Event: Codable {
    var date: Date
}

let json = "{\"date\":1577836800}"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
let e = try decoder.decode(Event.self, from: json.data(using: .utf8)!)
print(e.date.timeIntervalSince1970)

カスタム日付形式

標準ではない形式には、.formatted(_:) を使って DateFormatter を指定します。これにより、時刻を含まない 2020-01-01 のような日付も処理できます。

import Foundation

struct Event: Codable { var date: Date }

let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd"
fmt.timeZone = TimeZone(identifier: "UTC")
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(fmt)
let e = try decoder.decode(Event.self, from: "{\"date\":\"2020-01-01\"}".data(using: .utf8)!)
print(e.date.timeIntervalSince1970)

戦略の組み合わせ

キー戦略と日付戦略は同じデコーダーに同時に設定できます。これにより、型ごとの定型コードを一切書かずに、snake_caseとISO-8601を使うAPIを処理できます。

import Foundation

struct LogEntry: Codable {
    var eventName: String
    var occurredAt: Date
}

let json = "{\"event_name\":\"login\",\"occurred_at\":\"2020-01-01T00:00:00Z\"}"
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .iso8601
let entry = try decoder.decode(LogEntry.self, from: json.data(using: .utf8)!)
print(entry.eventName, entry.occurredAt.timeIntervalSince1970)

戦略とCodingKeysの比較

グローバル戦略は、形式が統一されたAPIに適しています。異なるキーが少数だけ存在する場合や、名前が不規則な場合は、明示的な CodingKeys 列挙型によってキーごとに正確に制御できます。両方を組み合わせることも可能です。

import Foundation

struct Item: Codable {
    var itemName: String
}

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let i = try decoder.decode(Item.self, from: "{\"item_name\":\"Pen\"}".data(using: .utf8)!)
print(i.itemName)

理解度チェック:戦略

デコード戦略についての理解度を確認しましょう。

まとめ:キー戦略と日付戦略

コーダーのグローバル設定について学びました。

  • keyDecodingStrategy = .convertFromSnakeCase はsnake_caseをキャメルケースに対応付けます。.convertToSnakeCase は反対方向にエンコードします。
  • dateDecodingStrategy = .iso8601 はISOタイムスタンプを解析します。.secondsSince1970 と .formatted(_:) を使えば、その他の形式にも対応できます。
  • 戦略は、ネストされたすべての型に一律に適用されます。
  • 形式が統一されたAPIには戦略を、不規則なAPIには CodingKeys を使います。

よくある質問

「キーと日付のデコード戦略」レッスンは無料ですか?

はい。「キーと日付のデコード戦略」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。

「キーと日付のデコード戦略」で何を学びますか?

snake_caseや日付のデコード戦略を使用します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Swift Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「キーと日付のデコード戦略」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSwift Academyレッスンでコードを書いて実行できますか?

はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 名前変更のためのCodingKeys
  2. キーと日付のデコード戦略
  3. 手動のencode(to:)とinit(from:)
  4. 異種JSONのデコード
← Swift Academyに戻る