I have a class modelling question with Swift. I have a range of classes that each do the same task (in my example below, Decoding), but they are specialised and each produce a different type of object.
In some cases I will want to be able to talk about my Decoders generally such as getGeneralInfo() or getDecoderForIdentifier(). In other cases, such as where I am doing a decode operation, I will either instantiate the class directly or use as?.
The following code does not work because you can't use Decoder as a return type when it has an associated type.
My solution is to remove decode() from the protocol and have each class just implement its own. I then need to instantiate concrete classes directly where they are needed. This is workable but it makes me sad.
Is there any way I can rejuggle this to have the compiler enforce "all Decoders should have a decode() method according to their associatedtype"?
I have tried using a generic superclass but it requires me to provide a method body for decode(), which is pretty gnarly if your return type isn't optional.
protocol Decoder { associatedtype Model func getGeneralInfo() -> GeneralInfo func decode(sourceData: Data) -> Model } // This return type is not allowed because Decoder has an associated type func getDecoderForIdentifier(id: String) -> Decoder { if id == "mp3" { return Mp3Decoder() } if id == "wave" { return WaveDecoder() } /* ... */ } class Mp3Decoder: Decoder { typealias Model = Mp3Info func getGeneralInfo() -> GeneralInfo { let info = GeneralInfo() /* ... */ return info } func decode(sourceData: Data) -> Model { let result = Mp3Info() /* ... */ return result } } class WaveDecoder: Decoder { typealias Model = WaveInfo /* ... similar to mp3 ... */ }