I have a Swift 3 project where I'm declaring a protocol with an associated type like this:
protocol ViewModelContainer {
associatedtype ViewModelType
var viewModel: ViewModelType! { get set }
}
And I want to check if two objects implement ViewModelContainer
and it's associated type ViewModelType
to make the assignment in a 'generic' way.
Ideally I'd like to do something like this:
if let container = container as? ViewModelContainer, let model = model as? container.ViewModelType {
container.viewModel = model
}
But I can't cast container
to ViewModelContainer
:
Protocol 'ViewModelContainer' can only be used as a generic constraint because it has Self or associated type requirements
My current workaround is to fall back to specific classes and their associated types directly, but it leaves my code very verbose and error prone:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? MediaPlaySelectionViewController, let vm = sender as? MediaPlaySelectionViewModel {
vc.viewModel = vm
}
if let vc = segue.destination as? SearchResultsViewController, let vm = sender as? SearchResultsViewModel {
vc.viewModel = vm
}
if let vc = segue.destination as? ReviewDetailsViewController, let vm = sender as? ReviewDetailsViewModel {
vc.viewModel = vm
}
if let vc = segue.destination as? ReviewComposerViewController, let vm = sender as? ReviewComposerViewModel {
vc.viewModel = vm
}
}
I tried using generic UIViewController
s, but got stuck because Objective-C doesn't recognize generic Swift classes and therefore can't be used in Storyboard.
ViewModelContainer
conform to that protocol, then you check for conformance to that protocol without bumping up against this issue. – BallpointBencontainer
statically typed as a type that conforms toViewModelContainer
? You may well be looking for a type eraser. – HamishViewModelType
as a protocol? – dichenAny
at some point to workaround it – redent84ViewModel
protocol. But it doesn't help here because each container must contain its specific view model class. – redent84