Thanks @Polyphonic, but I guess it requires a little bit more of context.
I can't say too much for NDA reasons, but I'll try to make an analogy ;-)
Let's say I have a Video framework that allows me to create video objects. Theses videos can be of certain type (Local, Youtube, Streamed). Each Video is not related (that's my first issue, but since I have to use this framework, I have no other way to tackle this). Add on top that this framework is an objC one 😬
Now let's say that I'm building a framework that allows me to load the various Video objects, and I want to leverage as much of Swift capabilities.
To do so, I started by creating an enum VideoType that "mirrors" the separated objC objects. So I have this
enum VideoType {
case local, youtube, streamed
}
Now, I create VideoManager objects that relies on a protocol that allows me to load and show a video. But, I want this objects to handle the underlying objC Video Objects.
To do so, I used an associatedType
protocol VideoManager {
associatedtype Video
func load()
func show()
var video: Video { get set }
}
Now I create dedicated objects that implement the behind-the-scene logic with the proper Video objects, one for each enum value.
Here's one for the sake of it
struct YoutubeVideoManager: VideoManager {
typealias Video = YoutubeVideo
func load() {}
func show() {}
var video: Video { ... }
}
Now, here is the part where it fails. I'd like to create a factory like object that would return the actual VideoManager depending on the enum
struct VideoFactory {
func videoManager(for videoType: VideoType) -> VideoManager {}
}
But in this example, it returns a VideoManager, not an actual implementation. I'd like that when I call videoManager(for: .youtube), it returns with a typesafe check a YoutubeVideoManager and if I try to call it like let _: LocalVideoManager = factory.videoManager(for: .youtube, then I get an error from compilation.
So far, the only thing I managed to do is to add a generic to the enum enum VideoType<T: VideoManager> and check at runtime that T is of type YoutubeVideoManager for the .youtube value, otherwise I throw an error. But it's a runtime check AND I have to declare my variables like this let _: = .factory.videoManager(for: VideoType<YoutubeVideoManager>.youtubewhich is pretty ugly I agree 😅
I hope I gave you enough context. I'm pretty sure it's not actually doable, but maybe I'm so stuck on that "dynamic typealias" that there is another solution more obvious that I don't see!
Thanks @Polyphonic