Search code examples
swiftswaggerswift4swagger-codegen

Swift 4 support for swagger code gen


I am facing an issue with generating swift models from YAML file.

swagger-codegen generate -i swagger_1.yaml -l swift4

below is one of the sample model. which is not building in swift 4. because of no Coding Key

import Foundation

open class User: Codable {

    public enum Sex: String, Codable { 
        case male = "male"
        case female = "female"
    }
    public var id: Int64?
    public var username: String?
    public var firstName: String?
    public var lastName: String?
    public var sex: Sex?



    public init(id: Int64?, username: String?, firstName: String?, lastName: String?, sex: Sex?) {
        self.id = id
        self.username = username
        self.firstName = firstName
        self.lastName = lastName
        self.sex = sex
    }


    // Encodable protocol methods

    public func encode(to encoder: Encoder) throws {

        var container = encoder.container(keyedBy: String.self)

        try container.encodeIfPresent(id, forKey: "id")
        try container.encodeIfPresent(username, forKey: "username")
        try container.encodeIfPresent(firstName, forKey: "firstName")
        try container.encodeIfPresent(lastName, forKey: "lastName")
        try container.encodeIfPresent(sex, forKey: "sex")
    }

    // Decodable protocol methods

    public required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: String.self)

        id = try container.decodeIfPresent(Int64.self, forKey: "id")
        username = try container.decodeIfPresent(String.self, forKey: "username")
        firstName = try container.decodeIfPresent(String.self, forKey: "firstName")
        lastName = try container.decodeIfPresent(String.self, forKey: "lastName")
        sex = try container.decodeIfPresent(Sex.self, forKey: "sex")
    }
}

posted this question in GitHub also.

https://github.com/swagger-api/swagger-codegen/issues/8289


Solution

  • You need to add enum CodingKeys and rewrite initFromDecoder/encode.

    Also in your case there is no need for separate encode/decode/CodingKeys at all because all properties of class are already Codable.

    open class User: Codable {
        ....
        enum CodingKeys: String, CodingKey {
            case id, username, firstName, lastName, sex
        }
    
        // Encodable protocol methods
    
        public func encode(to encoder: Encoder) throws {
    
            var container = encoder.container(keyedBy: CodingKeys.self)
    
            try container.encodeIfPresent(id, forKey: .id)
            try container.encodeIfPresent(username, forKey: .username)
            try container.encodeIfPresent(firstName, forKey: .firstName)
            try container.encodeIfPresent(lastName, forKey: .lastName)
            try container.encodeIfPresent(sex, forKey: .sex)
        }
    
        // Decodable protocol methods
    
        public required init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
    
            id = try container.decodeIfPresent(Int64.self, forKey: .id)
            username = try container.decodeIfPresent(String.self, forKey: .username)
            firstName = try container.decodeIfPresent(String.self, forKey: .firstName)
            lastName = try container.decodeIfPresent(String.self, forKey: .lastName)
            sex = try container.decodeIfPresent(Sex.self, forKey: .sex)
        }
    }