Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Foundation
- let jsonData = """
- {
- "name": "Kazi Abdullah Al Mamun",
- "id": 1,
- "user_name": "nightwalker",
- "address": {
- "street": "my street address",
- "apt_suite": "my apartment and suite",
- "city": "Dhaka",
- "country": "Bangladesh"
- }
- }
- """.data(using: .utf8)!
- struct User: Codable {
- //Mark: - Non nested properties
- let name: String
- let id: Int
- let userName: String
- //Mark: - Nested objects properties
- let street: String
- let aptSuite: String
- let city: String
- let country: String
- //Mark: - Self object keys
- private enum UserKeys: String, CodingKey {
- case name
- case id
- case userName = "user_name"
- //Key for nested object
- case address
- }
- //Mark: - Nested Object Address's keys
- private enum AddressKeys: String, CodingKey {
- case street
- case aptSuite = "apt_suite"
- case city
- case country
- }
- init(from decoder: Decoder) throws {
- let selfContainer = try decoder.container(keyedBy: UserKeys.self)
- self.name = try selfContainer.decode(String.self, forKey: .name)
- self.id = try selfContainer.decode(Int.self, forKey: .id)
- self.userName = try selfContainer.decode(String.self, forKey: .userName)
- //Address objects Container from selfContainer
- let addressContainer = try selfContainer.nestedContainer(keyedBy: AddressKeys.self, forKey: .address)
- self.street = try addressContainer.decode(String.self, forKey: .street)
- self.aptSuite = try addressContainer.decode(String.self, forKey: .aptSuite)
- self.city = try addressContainer.decode(String.self, forKey: .city)
- self.country = try addressContainer.decode(String.self, forKey: .country)
- }
- }
- print("No encoder applied yet..........")
- if let user = try? JSONDecoder().decode(User.self, from: jsonData) {
- print("Decoded \(user)")
- if let encodedUser = try? JSONEncoder().encode(user) {
- print("Encoded User: \(String(data: encodedUser, encoding: .utf8)!)")
- /**
- From output we can see that Encoded User Json is not same as Json from which we decoded User.
- If we want to make nested Json from flat model we need to write our own encoder.
- */
- }
- }
- print(".................................\n\n")
- extension User {
- // In playground it may show error "Invalid redeclaration of 'encode(to:)'"
- // Overlook and run.
- func encode(to encoder: Encoder) throws {
- var userContainer = encoder.container(keyedBy: UserKeys.self)
- try userContainer.encode(self.name, forKey: .name)
- try userContainer.encode(self.id, forKey: .id)
- try userContainer.encode(self.userName, forKey: .userName)
- var addressContainer = userContainer.nestedContainer(keyedBy: AddressKeys.self, forKey: .address)
- try addressContainer.encode(self.street, forKey: .street)
- try addressContainer.encode(self.aptSuite, forKey: .aptSuite)
- try addressContainer.encode(self.city, forKey: .city)
- try addressContainer.encode(self.country, forKey: .country)
- }
- }
- print("Encoder applied..........")
- if let user = try? JSONDecoder().decode(User.self, from: jsonData) {
- print("Decoded \(user)")
- if let encodedUser = try? JSONEncoder().encode(user) {
- print("Encoded User: \(String(data: encodedUser, encoding: .utf8)!)")
- /**
- From output we can see that Encoded User Json and Json from which we decoded User is same :).
- */
- }
- }
- print("..........................")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement