Skip to content

Instantly share code, notes, and snippets.

@brunabaudel
Created October 6, 2023 08:58
Show Gist options
  • Save brunabaudel/381287e5f753734821b0ac707bbe4e44 to your computer and use it in GitHub Desktop.
Save brunabaudel/381287e5f753734821b0ac707bbe4e44 to your computer and use it in GitHub Desktop.

Revisions

  1. brunabaudel created this gist Oct 6, 2023.
    112 changes: 112 additions & 0 deletions BlogPost
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,112 @@
    import Foundation

    struct User: Codable {
    var username: String
    var email: String
    }

    struct Comment: Codable {
    var text: String
    var date: Date
    var user: User
    }

    struct BlogPost: Codable {
    var title: String
    var content: String
    var datePublished: Date
    var comments: [Comment]

    enum CodingKeys: String, CodingKey {
    case title
    case content
    case datePublished = "date_published"
    case comments
    }

    enum CommentCodingKeys: String, CodingKey {
    case text
    case date
    case user
    }

    init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    title = try container.decode(String.self, forKey: .title)
    content = try container.decode(String.self, forKey: .content)
    datePublished = try container.decode(Date.self, forKey: .datePublished)

    var commentsContainer = try container.nestedUnkeyedContainer(forKey: .comments)
    var commentsArray: [Comment] = []
    while !commentsContainer.isAtEnd {
    let commentContainer = try commentsContainer.nestedContainer(keyedBy: CommentCodingKeys.self)
    let text = try commentContainer.decode(String.self, forKey: .text)
    let date = try commentContainer.decode(Date.self, forKey: .date)
    let user = try commentContainer.decode(User.self, forKey: .user)
    let comment = Comment(text: text, date: date, user: user)
    commentsArray.append(comment)
    }
    comments = commentsArray
    }

    func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(title, forKey: .title)
    try container.encode(content, forKey: .content)
    try container.encode(datePublished, forKey: .datePublished)

    var commentsContainer = container.nestedUnkeyedContainer(forKey: .comments)
    for comment in comments {
    var commentContainer = commentsContainer.nestedContainer(keyedBy: CommentCodingKeys.self)
    try commentContainer.encode(comment.text, forKey: .text)
    try commentContainer.encode(comment.date, forKey: .date)
    try commentContainer.encode(comment.user, forKey: .user)
    }
    }
    }

    let json = """
    {
    "title": "Sample Blog Post",
    "content": "This is the content of the blog post.",
    "date_published": "2023-10-06T08:00:00Z",
    "comments": [
    {
    "text": "Great post!",
    "date": "2023-10-06T10:00:00Z",
    "user": {
    "username": "user1",
    "email": "[email protected]"
    }
    },
    {
    "text": "Thanks for sharing.",
    "date": "2023-10-06T11:00:00Z",
    "user": {
    "username": "user2",
    "email": "[email protected]"
    }
    }
    ]
    }
    """

    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .iso8601
    decoder.keyDecodingStrategy = .convertFromSnakeCase

    do {
    let blogPost = try decoder.decode(BlogPost.self, from: Data(json.utf8))
    print("Title: \(blogPost.title)")
    print("Content: \(blogPost.content)")
    print("Date Published: \(blogPost.datePublished)")
    print("Comments:")
    for comment in blogPost.comments {
    print(" Text: \(comment.text)")
    print(" Date: \(comment.date)")
    print(" User: \(comment.user.username) (\(comment.user.email))")
    print("-----")
    }
    } catch {
    print("Error decoding JSON: \(error)")
    }