Protocol can only be used as a generic constraint

generics, mkannotation, protocols, swift

Solution

Updated

Sorry, I make mistakes. But there is no way to cast a protocol with `associated type`.

Hope this will help.

As i known the `routePresentable.getRouteLocations` has nothing to do with protocol `MapPresentable`.

So you can divide `RoutePresentable` to two protocol:

protocol MapPresentable {
    associatedtype AnnotationElement: MKAnnotation
    var annotations: [AnnotationElement] { get }
}

class MapViewController<M: MapPresentable>: UIViewController {
    var mapPresentable: M!

}

protocol RoutePresentable: MapPresentable, CanGetRouteLocations {}

protocol CanGetRouteLocations {
    var getRouteLocations: [CLLocation] { get }
}


if let routePresentable = mapPresentable as? CanGetRouteLocations {
    showRoute(routePresentable.getRouteLocations)
}

Original

Because `routePresentable.annotations`'s Type is unprovided,

You can just remove `associatedtype AnnotationElement: MKAnnotation`.

Or user generic struct instead:

struct MapPresentable<AnnotationElement: MKAnnotation> {
    var annotations: [AnnotationElement] = []
}

struct RoutePresentable<AnnotationElement: MKAnnotation> {
    var mapPresentable: MapPresentable<AnnotationElement>
    var getRouteLocations: [CLLocation] = []
}

class MapViewController<AnnotationElement: MKAnnotation>: UIViewController {

    var mapPresentable: MapPresentable<AnnotationElement>!

}

if let routePresentable = mapPresentable as? RoutePresentable<MKAnnotation> {
    showRoute(routePresentable.getRouteLocations)
}

Problem

I have a MapViewController for presenting annotations on map. It contains an object of type MapPresentable. ``` protocol MapPresentable { associatedtype AnnotationElement: MKAnnotation var annotations: [AnnotationElement] { get } } class MapViewController<M: MapPresentable>: UIViewController { var mapPresentable: M! } ``` MapViewController can also present route on map in case `mapPresentable` conforms to RoutePresentable protocol. ``` protocol RoutePresentable: MapPresentable { var getRouteLocations: [CLLocation] { get } } ``` But when checking made inside `MapViewController` ``` if let routePresentable = mapPresentable as? RoutePresentable { showRoute(routePresentable.getRouteLocations) } ``` I got this Error: ``` Protocol 'RoutePresentable' can only be used as a generic constraint because it has Self or associated type requirements ```

Original source