Chapter 22, Challenge 3: Encoding and Decoding Types (Swift 4th edition)

My solution below:

import Cocoa

struct Spaceman: Codable {
    var name: String
    var race: String
}

struct Spaceship {
    var name: String
    var crew: [Spaceman]
    
    enum CodingKeys: String, CodingKey {
        case name = "spaceship_name"
        case crew
    }
}

struct EarthTransmission: Codable {
    var name: String
    var captain: Spaceman
    var officer: Spaceman
    
    enum CodingKeys: String, CodingKey {
        case name
        case captain
        case officer
    }
}

extension Spaceship: Encodable {
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: EarthTransmission.CodingKeys.self)
        try container.encode(name, forKey: .name)
        // Assume index 0 is always captain, index 1 is always officer
        try container.encode(crew[0], forKey: .captain)
        try container.encode(crew[1], forKey: .officer)
    }
}

extension Spaceship: Decodable {
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: EarthTransmission.CodingKeys.self)
        name = try values.decode(String.self, forKey: .name)
        
        let captain = try values.decode(Spaceman.self, forKey: .captain)
        let officer = try values.decode(Spaceman.self, forKey: .officer)
        
        crew = [Spaceman]()
        crew.append(captain)
        crew.append(officer)
    }
}

// Create JSON transmission from Earth
let earthTransmission = EarthTransmission(name: "USS Enterprise", captain: Spaceman(name: "Spock", race: "Human"), officer: Spaceman(name: "Worf", race: "Klingon"))
let earthEncoder = JSONEncoder()
let earthTransmissionData = try earthEncoder.encode(earthTransmission)

// Test the JSON string
if let earthTransmissionString = String(bytes: earthTransmissionData, encoding: .utf8) {
    print(earthTransmissionString)
}

// Decoding Earth's transmission
let spaceshipDecoder = JSONDecoder()
let message = try spaceshipDecoder.decode(Spaceship.self, from: earthTransmissionData)

print(message)

/*
 Output:
 
 {"name":"USS Enterprise","captain":{"name":"Spock","race":"Human"},"officer":{"name":"Worf","race":"Klingon"}}
 Spaceship(name: "USS Enterprise", crew: [__lldb_expr_18.Spaceman(name: "Spock", race: "Human"), __lldb_expr_18.Spaceman(name: "Worf", race: "Klingon")])
 
 */

@choonsiong Is there something wrong with your code, and you have a question? Or were you providing an alternative solution to one given in the book?

This topic was automatically closed after 166 days. New replies are no longer allowed.