Reputation: 181
I'm writing a small class which helps to fetch paged data automatically.
I have following delegate:
protocol DataAPIDelegate: class {
func fetchItemsForPage<T>(api: DataAPI<T>, page: Int, onFinish: ([T] -> ())
}
And DataAPI class, which stores delegate:
class DataAPI<T> {
weak var delegate: DataAPIDelegate? = nil
//...
//some other methods
}
Then, what I want to do is to write a view controller which uses DataAPI and communicates with this object by DataAPIDelegate:
class CarsViewController: DataAPIDelegate {
var dataAPI = DataAPI<Car>
// MARK :- DataAPIDelegate
func fetchItemsForPage<T>(api: DataAPI<T>, page: Int, onFinish: ([T] -> ()) {
let cars: [Car] = //some method for getting cars
onFinish(cars)
}
}
And I get the error: Cannot invoke 'onFinish' with an argument list of type '([Car])'
in the line: onFinish(cars)
.
I think about it for a few hours and I don't have any idea why it doesn't work. Anyone meets that problem?
Upvotes: 2
Views: 1155
Reputation: 301
Generic delegates aren't possible in Swift, if they aren't just functions. Because functions (closures) can be generic. See my gist where I tried to resolve the same problem: https://gist.github.com/artyom-razinov/fe8c2b7611a0ba3bd2a3
Upvotes: 0
Reputation: 10136
Generic functions provide single template implementation for multiple types referred by T
, while what it seems you are trying to do is to provide an implementation of fetchItemsForPage
method specifically for Car
type.
The way it would work is:
protocol DataAPIDelegate: class {
func fetchItemsForPage<T>(api: DataAPI<T>, page: Int, onFinish: ([T] -> ()))
}
class DataAPI<T> {
weak var delegate: DataAPIDelegate? = nil
//...
//some other methods
}
struct Car { }
class CarsViewController: DataAPIDelegate {
var dataAPI = DataAPI<Car>()
// MARK :- DataAPIDelegate
func fetchItemsForPage<T>(api: DataAPI<T>, page: Int, onFinish: ([T] -> ())) {
let items: [T] = [T]()
onFinish(items)
}
}
... while what you are trying to do is:
struct Bike { }
class BikesViewController: DataAPIDelegate {
var dataAPI = DataAPI<Bike>()
// MARK :- DataAPIDelegate
func fetchItemsForPage<Bike>(api: DataAPI<Bike>, page: Int, onFinish: ([Bike] -> ())) {
let items: [Bike] = [Bike]()
onFinish(items)
}
}
... but in the latter snippet Bike
is not a type but a placeholder, which works just the same as if you would use T
.
Upvotes: 1