How to implement a protocol function with a Codable param

Hi, maybe this is a silly question but I'm trying to use this protocol

protocol BusinessModel {
    func parseFrom(_ apiModel: Codable) -> Self
}

Then I want to implement this in my struct

extension MyBusinessType {
  func parseFrom(_ apiModel: MyCodableApiType) -> MyBusinessType {
    ...
  }
}

But compiler is forcing me to implemented like this

extension MyBusinessType {
  func parseFrom(_ apiModel: any Codable) -> MyBusinessType {
    ...
  }
}

Losing all MyCodableApiType information. I know I can do a cast inside but I don't want to rely on that.

What I'm doing wrong?

Thanks for your time

desugars into

protocol BusinessModel {
    func parseFrom(_ apiModel: any Codable) -> Self
}

Note the added any, which by definition erases concrete types from the function signature. Have you tried writing it using some instead?

protocol BusinessModel {
    func parseFrom(_ apiModel: some Codable) -> Self
}

I just tried with some and get similar error, is forcing me to implement it like this

    func parseFrom(_ apiModel: some Codable) -> MyBusinessType {
        
    }
protocol BusinessModel {
    associatedtype ApiModel: Codable
    func parseFrom(_ apiModel: ApiModel) -> Self
}
4 Likes

Ah, crap, I knew it was a simple solution. That was it.

Thank you @sveinhal

To not loose type information, you need to add it to your protocol, which is what associatedtype is for. Your initial version isn't saving this information, as it actually declares any Codable (I really wish Swift 6 didn't end up keeping this implicit), stating that you expect just any type and don't care about specific one. some isn't working for the same reason, plus it won't give you any upsides in that case as you need to preserve concrete type information in your code.

2 Likes