Eddie
Eddie

Reputation: 1942

Can I write protocol behave similar to Encodable & Decodable?

The swift4's Codable protocol is extremely useful. It provide default implementation functions if the conformation is rightly defined.

E.g. this is totally fine:

struct Good: Codable {
    var foo: String // Non-optional
    var bar: Int?  // Optional
}

but this one will raise compile error with the request to create protocol conforming

struct Bad: Codable {
   var foo: UIButton // Non-optional raise compile error for not conforming Codable Protocol
   var bar: UIView? // optional is okay (not compile error because when decode failed, it fallback to nil)
   var codable: SomeCodable // if the property is also Codable, then it's fine too!
}

So, the question is: Can I write a protocol that can require its conformance to follow itself (like properties need to conform same protocol)?

If yes, how? If no, why?

Also, I'd also like to know how defining CodingKeys inside the struct can change the encode/decode behaviour? Can I make something like that in my protocol as well?

Upvotes: 0

Views: 246

Answers (1)

DoesData
DoesData

Reputation: 7047

Martin is correct you cannot make this on your own without touching the compiler.

First let's take a look at this basic example where I explain how coding keys are used.

struct CodableStruct: Codable {
let primitive: Int // No issues yet

enum CodingKeys: String, CodingKey {
    case primitive
    // This is the default coding key (i.e the JSON has structure ["primitive": 37]
    // You can change this key to anything you need
    //
    // ex case primitive = "any_thing_you_want"
    // JSON has to have structure ["any_thing_you_want": 37]
}

}

Changing the codingKey just changes the key the code will use when looking to "decode" that value from your JSON.

Now let's talk about the compiler. Let's say we create another struct

struct NotCodableStruct {
    let number: Double
}

This struct does not conform to Codable. If we go and add this into our previous struct we have:

struct CodableStruct: Codable {
    let primative: Int
    let notCodable: NotCodableStruct // doesn't compile because this doesn't conform to codable

    enum CodingKeys: String, CodingKey {
        case primative
        case notCodable
    }
}

Since NotCodableStruct does not conform to Codable the compiler complains. In other words all variables in a struct or object that conforms to Codable must also conform to Codable. See the below screenshot for more information.

compiler error

Of course if you make NotCodableStruct conform to Codable everyone will be happy again. Since there is no way for you to enforce the requirement that all variables conform to Codable you cannot make a similar protocol.

Upvotes: 2

Related Questions