1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Swift】Dateを含むStructのencoder/decoder

Last updated at Posted at 2024-07-09

次のようなStructを例にencoder/decoderを実装します。

Post.swift
struct Post {
    
    var id: String
    var text: String
    var createdAt: Date
    
    init(id: String, text: String, createdAt: Date) {
        self.id = id
        self.text = text
        self.createdAt = createdAt
    }
    
}

Swiftでは、Date型の変数を単純にencodeするとtimeIntervalSinceReferenceDate: TimeIntervalになります。
そのため、データベース等に保存する際はISO8601形式などの文字列に変換すると便利です。

Post.swift
extension Post: Codable {
    
    enum CodingKeys: String, CodingKey {
        case id
        case text = "text_data"
        case createdAt
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(text, forKey: .text)
        let formatter = ISO8601DateFormatter()
        let dateString = formatter.string(from: createdAt)
        try container.encode(dateString, forKey: .createdAt)
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.id = try container.decode(String.self, forKey: .id)
        self.text = try container.decode(String.self, forKey: .text)
        let dateString = try container.decode(String.self, forKey: .createdAt)
        let formatter = ISO8601DateFormatter()
        if let date = formatter.date(from: dateString) {
            self.createdAt = date
        } else {
            throw DecodingError.dataCorruptedError(forKey: .createdAt, in: container, debugDescription: "")
        }
    }
    
}

実際に使ってみましょう。
まずはencodeです。

func addPost() {
    let post = Post(id: "aaa", text: "Hello!", createdAt: Date())
    let encoded = try! JSONEncoder().encode(post)
    do {
        guard let jsonObject = try JSONSerialization.jsonObject(with: encoded, options: []) as? [String: Any] else { return }
        print(jsonObject)
    } catch {}
}
["createdAt": 2024-07-09T15:30:26Z, "text_data": Hello!, "id": aaa]

ちゃんとencodeできました。
次に、decodeもやってみましょう。

let jsonData = """
{
   "id": "aaa",
   "createdAt": "2024-07-09T15:02:51Z",
   "text_data": "Hello!"
}
"""

func fetchPost(){
    guard let data = jsonData.data(using: .utf8) else { return }
    do {
        let decoded = try JSONDecoder().decode(Post.self, from: data)
        print(decoded)
    } catch {}
}
Post(id: "aaa", text: "Hello!", createdAt: 2024-07-09 15:02:51 +0000)

受け取ったString型の日付をdecodeしてDate型にすることができました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?