Here are my structures (I can have lot more, that why I need a generic way to do with MyProtocol):
protocol MyCustomCodable {
static func buildQuery()
}
struct A: MyCustomCodable {
...
}
struct B: MyCustomCodable {
...
}
...
Then, my problem: I have a code somewhere that I apply on a group of them:
func updateAllData(customCodableArrays: [[some MyCustomCodable]]) {
for customCodableArray in customCodableArrays {
type(of: dbCodablesArray).Element.buildQuery()
}
}
let As: [A] = [A(), A()]
let Bs: [B] = [] // some arrays can be empty ! That's why buildQuery is static.
updateAllData([As, Bs])
But here, Swift is complaining that in the call to updateAllData, B cannot be converted to A.
I also tried something like this:
func updateAllData(customCodableArrays: [some MyCustomCodable]...) {
for customCodableArray in customCodableArrays {
type(of: dbCodablesArray).Element.buildQuery()
}
}
let As: [A] = [A(), A()]
let Bs: [B] = []
updateAllData([As, Bs])
But 'some' seems not allowed on variadic.
I tried with any (or without any, since it is implicit):
func updateAllData(customCodableArrays: [[any MyCustomCodable]]) {
for customCodableArray in customCodableArrays {
type(of: dbCodablesArray).Element.buildQuery()
}
}
let As: [A] = [A(), A()]
let Bs: [B] = []
updateAllData([As, Bs])
But here, it's the call to updateAllData which fails because "Static member 'updateAllData' cannot be used on protocol metatype '(any MyCustomCodable).Type'"
The only solution I found was to pass arrays through individual arguments to updateAllData, with some keyword. But that's not a valid solution since I don't know how much tables I will need, and it enforce me to duplicate (more or less) the code for each of them (I cannot simply iterate on all arrays).
... I don't see how to solve my problem... Please, help !
I tried using any, using some, using variadic, using Any, or casting.
You can also use parameter packs to do this.
func updateAllData<each T: MyCustomCodable>(customCodableArrays: repeat [each T]) {
repeat type(of: each customCodableArrays).Element.buildQuery()
}
updateAllData(customCodableArrays: As, Bs)
or if the contents of the arrays don't matter, take the metatypes directly:
func updateAllData<each T: MyCustomCodable>(types: repeat (each T).Type) {
repeat (each types).buildQuery()
}
updateAllData(types: A.self, B.self)
If buildQuery
returns something, say, a Query
, you can collect all of them in an array like this:
func updateAllData<each T: MyCustomCodable>(types: repeat (each T).Type) {
var queries = [Query]()
repeat array.append((each types).buildQuery())
}