Conforme al protocolo MKAnnotation mediante un protocolo personalizado

Quiero get 2 o más types de objects diferentes en un map fácilmente. Swift 2.0, quería usar protocolos.

Creé un protocolo que estos objects también tienen que cumplir. Supongo que ahora cualquier elemento se ajusta a PinProtocol como esencialmente lo mismo que ser un MKAnnotation … ¡solo más!

protocol PinProtocol: MKAnnotation { // stuff } 

Tengo 2 classs, personal y clientes

Ambos se ajustan a PinProtocol (que luego también debe cumplir con MKAnnotation)

Sé que esto está funcionando como si estableciera mi class como tal,

 class Client: NSObject, PinProtocol { //var coordinate:CLLocationCoordinate2D // Leave out get doesn't conform to protocol warning as expected } 

Entonces, esto me dice que ese PinProtocol está funcionando como se esperaba, ya que los elementos que necesitan adherirse al PinProtocol también se ajustan al protocolo MKnnotation también. Porque la coorderada: CLLocationCoordinate2D, es requerida por MKAnnotation.

Entonces, ¿por qué tengo este problema?

 let staffAndClients = [PinProtocol]() mapView.addAnnotations(staffAndClients) // not allowed! //mapView.addAnnotations(pins as! [MKAnnotation]) // also not allowed 

El error es que no se puede convertir el valor de tipo [PinProtocol] en el argumento esperado [MKAnnotation]

No es compatible PinProtocol con MKAnnotation, así que debería funcionar.

Pero hacer esto funciona bien

 let staff = [Staff]() mapView.addAnnotations(staff) // no problem let clients = [Client]() mapView.addAnnotations(clients) // no problem 

Puedo solucionar el problema con AnyObject, pero ¿por qué no puedo usar PinProtocol? Lo que para mí parece más limpio y la idea general de las extensiones de protocolo.

Gracias por cualquier ayuda.

Addit …

La forma en que lo estoy solucionando para aquellos que se enfrentan a un problema similar es

 var pins = [AnyObject]() mapView.addAnnotations(pins as! [MKAnnotation]) 

Considere el protocol como una plantilla, puede usar esa plantilla para hacer algo útil como la presentación esqueuer, pero no puede usar la plantilla misma para ninguna presentación.

Eso es porque el protocolo carece de la implementación de los methods o properties. Para realmente get un object de ese protocolo particular, estos methods deben implementarse. Java en ese caso le permite subclasificar de forma anónima un protocolo y lo obliga a implementar los methods requeridos. (Java lo llama interface , no lo confunda con la interface Objective-C)

A diferencia de Java, Swift no es compatible con la creación de subclasss anónimas, por lo que cualquier class que sea un protocolo no puede crear objects en Objective-C y Swift. La única forma de ejemplificarlos es hacer que otra class ( interface en el Objetivo C) cumpla ese protocolo y cree una instancia de esa class en particular, Staff y Client en su caso. Sin embargo, puede tener una variable con el tipo de protocolo de la siguiente manera:

 let staff = [PinProtocol]() //PinProtocol type array. can hold any type of objects that conform to this protocol 

staff en este caso es Array de tipo PinProtocol , no conoce ninguna otra información con respecto al object creado.

Editar:

Acabo de entender tu pregunta correctamente. Sí, podemos declarar una matriz de tipo swift por nombres de protocol . Y esa matriz puede contener objects de las classs que se ajustan al protocolo. Su syntax de declarar matriz es correcta.

 let staffAndClients = [PinProtocol]() 

Respecto al error El error es que no se puede convertir el valor de tipo [PinProtocol] en el argumento esperado [MKAnnotation] documentaciones y descubrí que el método addAnnotations() toma una matriz de AnyObject siguiente manera:

 func addAnnotations(annotations: [AnyObject]!) //in MKMapView 

Ahora la parte complicada es que MKAnnotation no henetworkinga de AnyObject , sino de NSObjectProtocol es decir:

 protocol MKAnnotation : NSObjectProtocol 

Mientras que AnyObject también henetworkinga de NSObjectProtocol , por lo que es hermano de MKAnnotation es por eso que está recibiendo un error, porque no puede pasar object con types de MKAnnotation , porque no son AnyObject en su jerarquía primaria.

Después de lidiar con la molestia de la fuente de datos de MapViewController

 var pins = [AnyObject]() 

Llegué a la conclusión de que podría fácilmente evitar todos los problemas asociados de la comprobación de types y utilizar la matriz preferida de PinProtocols

 var pins = [PinProtocol]() 

La solución fue simplemente

 func addToMap() { let mappingPins = pins.map{ $0 as AnyObject } mapView.addAnnotations(mappingPins as! [MKAnnotation]) mapView.showAnnotations(mappingPins as! [MKAnnotation], animated: true) }