2

I have struct that conforms to the Codable-protocol. I implemented a custom encode-func so that I have control over the encoding process. But I don't need this custom encoding in all cases, sometimes I want to rely on the encoding of Foundation itself. Is it possible to tell the JSONEncoder what kind of encoding I want (like creating an encoding strategy)?

This is a simplified version of my code:

struct User: Codable {
    var name: String
    var age: Int
    var phone: PhoneNumber
    
    struct PhoneNumber: Codable {
        var countryCode: Int
        var number: Int
        
        enum CodingKeys: CodingKey {
            case countryCode, number
        }
        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            // I would like to have control over the next line, so that either
            // the countryCode is encoded or not, like:
            // if conditon {
                try container.encode(self.countryCode, forKey: .countryCode)
            // }
            try container.encode(self.number, forKey: .number)
        }
    }
}

let user = User(name: "John", age: 12, phone: User.PhoneNumber(countryCode: 49, number: 1234567))
let jsonData = try! JSONEncoder().encode(user)
print(String(data: jsonData, encoding: .utf8)!)

UPDATE

To answer one of the comments: It's not really about including or excluding one property, it's more about changing the type or content of a property:

public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    // if conditon {
        try container.encode("\(self.countryCode)".data(using: .utf8), forKey: .countryCode)
    // }
    try container.encode(self.number, forKey: .number)
}
Lupurus
  • 3,618
  • 2
  • 29
  • 59
  • If you comment that line of encoding the countryCode, it just doesn't encode to JSON. This is a simplified example, in my case I change the type of the property (I just wanted to make it easier to understand) – Lupurus Jul 07 '20 at 07:33
  • That is what I wanted to say: In my case I want to change the type. I'll update the question – Lupurus Jul 07 '20 at 07:45
  • And making it optional is no option, because as I said, sometimes I need the normal encoding and sometimes the other one (why? I use a library to save data in the database, therefore I need the "normal" encoding, but for sending the json string in the network I need a different encoding) – Lupurus Jul 07 '20 at 07:53
  • @Lupurus, I think what you're asking is if there is a way to fallback, except for specific properties, to the default encoding that would have happened if you didn't implement a custom `encode`. And my understanding is that it's not possible. The compiler synthesizes conformance to Codable, but it's an all-or-nothing deal, and as soon as you implement your own, you'd need to fully implement it. – New Dev Jul 07 '20 at 11:41
  • Answer's here: https://stackoverflow.com/questions/75355737/swift-encoding-multiple-encode-strategeis – Oded Ben Dov Aug 10 '23 at 11:14

0 Answers0