Reputation: 1262
I suspect I may be making the same mistake as described by Rob in this post here in that I should be doing this whole thing another way, but with that in mind:
I'm trying to use AlamofireObjectMapper in a generic way. It has a protocol
public protocol Mappable
I then have various model classes that adopt it
class Dog: Mappable
class Cat: Mappable
class Bird: Mappable
I have this method
func loadEntityArray<T: Mappable>(type: T.Type)
and the reason this is generic is because it calls a function load() that needs a completion block that uses this generic param. The 'type' argument is never actually used, but you can't make a func generic without the generic type being in the func's parameter list.
func load(completion:(Response<T, NSError> -> Void))
loadEntityArray is called from another method
func letsgo() { loadEntityArray(Dog.self); loadEntityArray(Cat.self) }
So far so good, this all works. But I want to pass an array of which models to load to letsgo() and I can't work out how to do this. If I change letsgo() to
func letsgo<T:Mappable>(models: [T.Type]) {
for mod in models {
loadEntityArray(mod)
}
}
and then call letsgo() with 1 param like
letsgo([Dog.self])
it works, but as soon as I have an array of 2 or more, I get a compiler error 'cannot convert value of type NSArray to expected argument type [_.Type]' I don't now how I would explicitly type this array either.
letsgo([Dog.self, Cat.self])
I've tried various permutations and nothing seems to work. Am I doing something impossible here? It seems to me the compiler has enough information at compile time for this to work, so I'm not sure if this is a syntax thing or I'm doing something wrong here with generics.
Upvotes: 1
Views: 451
Reputation: 1262
So in the end I came to the conclusion that this is not possible. I changed the code such that I pass in an enum to letsgo() and in a switch statement on that enum I call loadEntityArray(Dog.self) etc. etc. with an explicitly coded call, for each of my possible types. Then the compiler can see all the possible types and is happy.
Upvotes: 0
Reputation: 471
Looking at your function :
func letsgo<T:Mappable>(models: [T.Type])
Its model parameter should be an Array of all the same Type. So an array of only Dog Types for example. That's why
letsgo([Dog.self])
works but
letsgo([Dog.self, Cat.self])
won't as it has multiple Types.
The solution :
Use Mappable.Type directly :
func loadEntityArray(type: Mappable.Type) {}
func letsgo(models: [Mappable.Type]) {
for mod in models {
loadEntityArray(mod.self)
}
}
And cast your array of Types as an array of Mappable Types :
letsgo([Dog.self, Cat.self] as [Mappable.Type])
Hope this achieves what you're looking for !
Upvotes: 1