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.
Nested JSON data representing a blog post with comments, where each comment has a user and a date
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)")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment