El elemento NSArray no pudo coincidir con el tipo de elemento de matriz Swift

Tengo un object Core Data (Orden) que tiene un método para devolver una matriz de otro object Core Data (OrderWaypoint).

func getOrdenetworkingWaypoints() -> [OrderWaypoint] { let nameDescriptor = NSSortDescriptor(key: "stop_number", ascending: true) let sorted: [OrderWaypoint] = self.waypoints.sortedArrayUsingDescriptors([nameDescriptor]) as [OrderWaypoint] return sorted } 

Todo funciona como se espera en el objective principal cuando se usa el siguiente ciclo

 for waypoint in order.getOrdenetworkingWaypoints() { // do something } 

Pero cuando bash exactamente lo mismo en mi objective de testing

error grave: el elemento NSArray no pudo coincidir con el tipo de elemento de matriz Swift

He intentado lanzar los valores, pero parece que no pueden hacerlo funcionar. ¿Alguna idea de por qué funciona en el objective principal pero no en el objective de testing?

EDITAR

Bueno, descomponiéndolo aún más, el problema está sucediendo específicamente cuando trato de sacar un elemento de la matriz.

 var ordenetworkingList: [OrderWaypoint] = order.getOrdenetworkingWaypoints() for var i = 0; i < ordenetworkingList.count; i++ { var waypoint = ordenetworkingList[i] // do something } 

No se puede sortedArrayUsingDescriptors como sortedArrayUsingDescriptors devuelve un NSArray y debe copyr todos los elementos de esa matriz en la matriz Swift Typed.

 func getOrdenetworkingWaypoints() -> [OrderWaypoint] { let nameDescriptor = NSSortDescriptor(key: "stop_number", ascending: true) let sorted = [OrderWaypoint]() for elem in self.waypoints.sortedArrayUsingDescriptors([nameDescriptor]) { sorted.append(elem) } return sorted } 

En lugar de hacer toda la sorting en la memory, generalmente tendré esos methods auxiliares que obtienen datos relacionados que obtienen datos directamente de la database como:

 var ordenetworkingWayPoints: [WayPoint] { let request = NSFetchRequest(entityName: "Waypoint") request.sortDescriptors = NSSortDescriptor(key: "stop_number", ascending: true) request.pnetworkingicate = NSPnetworkingicate(format: "parent = %@", self) return try! managedObjectContext.executeFetchRequest(request) } 

El punto es que, en general, quiero que la database haga el gruñido de orderar mis datos en lugar del código. Y tampoco es mucho más código.

La causa más probable es que el error sea verdadero: al less uno de los elementos en self.waypoints no es realmente un OrderWaypoint . Es posible que tenga algún otro tipo que responda a los mismos posts. Puede tener una superclass de OrderWaypoint (¿está utilizando mogenerator, tal vez? ¿Son algunos de estos objects realmente _OrderWaypoint ?) ¿Está dando vueltas a los objects de tal forma que mienten sobre su verdadero tipo? KVO puede hacer esto.

El hecho de que esto falla en tu objective de testing aumenta la posibilidad de que te estás burlando de estos objects. ¿Es eso posible?

Comenzaré examinando cuidadosamente los contenidos de los self.waypoints de self.waypoints de self.waypoints para asegurarme de que realmente contiene lo que cree que hace.

La razón por la que ocurre solo en su objective de testing es que es un module diferente de su aplicación principal, por lo que obtendrá diferentes versiones de su class OrderWaypoint en cada module, que Swift considera que son diferentes classs: App.OrderWaypoint y AppTest.OrderWaypoint .

Estoy trabajando para resolver esto en mi propio proyecto, y lo actualizaré cuando tenga una buena solución 🙂

Actualización: para los proyectos de Swift, creo que la solución es eliminar los files .swift que no sean de testing del objective de testing y agregar @testable import YourAppModuleName a sus testings de Swift. Al parecer, este es el enfoque moderno y probablemente debería hacerse de todos modos. (Aunque si su aplicación es Swift, probablemente no tendrá este problema).

Esto no funcionó para mí, porque tengo testings escritas en Objective-C que necesitan acceder a mis classs Swift, y tuve problemas para encontrar un equivalente de Objective-C para importar el module Swift del objective de la aplicación.

Mi solución fue reescribir el código del problema en Objective-C, donde no realiza una comprobación de tipo tan estricta. En mi caso, fue fácil porque las funciones problemáticas se encontraban en una extensión de una class declarada originalmente en Objective-C, por lo que es fácil moverlas.

Actualización 2: una solución un poco turbia pero más simple es eliminar los files Swift de la aplicación del objective de testing y luego establecer las routes de búsqueda de encabezado en el objective de testing para apuntar a la carpeta DerivedSources desde el destino de la aplicación e include la App-Swift.h en las testings de Objective-C que lo necesitan, en lugar del file AppTest-Swift.h que ya no tiene las classs Swift de la aplicación porque acaba de eliminarlas del objective de testing.