I have struct that has parameter with protocol type
protocol CheckoutOrder {}
struct CheckoutOrderEntity: Encodable {
private enum CodingKeys: String, CodingKey {
case amount
case payment
}
let amount: Int
let payment: CheckoutOrder
}
Also have 2 structs which implements protocol CheckoutOrder
struct ApplePayOrderEntity: Encodable {
private enum CodingKeys: String, CodingKey {
case token
}
let token: ApplePayTokenEntity
}
extension ApplePayOrderEntity: CheckoutOrder { }
struct CheckoutPaymentEntity: Encodable {
private enum CodingKeys: String, CodingKey {
case terminalName
case shouldUseBalance
}
let shouldUseBalance: Bool
let terminalName: String
}
extension CheckoutPaymentEntity: CheckoutOrder { }
I have an error: Type 'CheckoutOrderEntity' does not conform to protocol 'Encodable' and CheckoutOrder protocol requires function 'encode(to:)'.... So, the main reason of using protocol is that payment can be type of ApplePayOrderEntity or CheckoutPaymentEntity. How to solve problem or what is best practice in this case?
First you need to make the protocol extend Encodable
to tell the compiler that anything that conforms to CheckoutOrder
also conforms to Encodable
protocol CheckoutOrder: Encodable {}
Then I would use generics for this and change CheckoutOrderEntity
to
struct CheckoutOrderEntity<Payment: CheckoutOrder>: Encodable {
private enum CodingKeys: String, CodingKey {
case amount
case payment
}
let amount: Int
let payment: Payment
}
Example
let checkout = CheckoutOrderEntity(amount: 1000,
payment: CheckoutPaymentEntity(shouldUseBalance: true,
terminalName: "terminal"))