You need Paginatable to be a generic. Then everything falls into place. You do not want it to declare an array of Itemable but an array of some Itemable adopter. That is exactly what a generic lets you say.
In other words:
protocol Paginatable {
var items: [Itemable] { get set }
}
...means: "Whoever adopts me (I'm looking at you, Fetcher), must declare that items is [Itemable]." That is not what you want Fetcher to have to say. But you are forcing Fetcher to say that.
Instead, say this:
protocol Paginatable {
associatedtype T : Itemable
var items: [T] { get set }
}
Now you are saying: "Whoever adopts me can declare items as an array of any type as long as that type adopts Itemable." That is exactly what you do want to say.
To illustrate further, this is illegal:
protocol Itemable { }
protocol Paginatable {
var items: [Itemable] { get set }
}
struct Dummy : Itemable {}
struct Fetcher : Paginatable { // error
var items: [Dummy]
}
But this is fine:
protocol Itemable { }
protocol Paginatable {
associatedtype T : Itemable
var items: [T] { get set }
}
struct Dummy : Itemable {}
struct Fetcher : Paginatable {
var items: [Dummy]
}
And that second thing is exactly what you want to say. Now that you've understood that, if you then want to make Fetcher a generic too, no problem:
protocol Itemable { }
protocol Paginatable {
associatedtype T : Itemable
var items: [T] { get set }
}
struct Dummy : Itemable {}
struct Fetcher <T:Itemable> : Paginatable {
var items: [T]
}