La asignación de relaciones en RestKit a través de una serie de ID no funciona

Estoy tratando de asignar usuarios y grupos a objetos CoreData a través de RestKit, manteniendo la relación entre los dos.

El JSON para los usuarios es algo así como

{"users":
  [{"fullname": "John Doe", "_id": "1"}
   ...
  ]
}

y el JSON para los grupos es algo así como

{"groups":
  [{"name": "John's group", "_id": "a",
    "members": ["1", "2"]
   ...
  ]
}

También tengo los correspondientes objetos de datos básicos,User yGroup, con una relación de uno a muchos entre grupos y usuarios. La propiedad de la relación enGroup se llamamembers y un separadoNSArray llamadomemberIDs contiene la matriz de ID de cadena de todos los usuarios miembros.

Lo que quiero lograr en RestKit es cargar estos objetos y tener la relación asignada para mí. El código para cargar a los usuarios es sencillo y estándar, y el código para cargar los grupos es algo así como

RKObjectManager* objectManager = [RKObjectManager sharedManager];
RKManagedObjectMapping* groupMapping = [RKManagedObjectMapping mappingForClass:[Group class] inManagedObjectStore:objectManager.objectStore];
groupMapping.primaryKeyAttribute = @"identifier";
[groupMapping mapKeyPath:@"_id" toAttribute:@"identifier"];
[groupMapping mapKeyPath:@"name" toAttribute:@"name"];
[groupMapping mapKeyPath:@"members" toAttribute:@"memberIDs"];
[objectManager.mappingProvider setMapping:groupMapping forKeyPath:@"groups"];

// Create an empty user mapping to handle the relationship mapping
RKManagedObjectMapping* userMapping = [RKManagedObjectMapping mappingForClass:[User class] inManagedObjectStore:objectManager.objectStore];

[groupMapping hasMany:@"members" withMapping:userMapping];
[groupMapping connectRelationship:@"members" withObjectForPrimaryKeyAttribute:@"memberIDs"];

RKObjectRouter* router = objectManager.router;

[router routeClass:[Group class] toResourcePath:@"/rest/groups/:identifier"];
[router routeClass:[Group class] toResourcePath:@"/rest/groups/" forMethod:RKRequestMethodPOST];
// Assume url is properly defined to point to the right path...
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:url usingBlock:^(RKObjectLoader *loader) {}];

Cuando ejecuto este código, aparece la siguiente advertencia varias veces (parece ser aproximadamente dos veces por relación):

2012-10-24 08:55:10.170 Test[35023:18503] W restkit.core_data.cache:RKEntityByAttributeCache.m:205 Unable to add object with nil value for attribute 'identifier': <User: 0x86f7fc0> (entity: User; id: 0x8652400 <x-coredata:///User/t01A9EDBD-A523-4806-AFC2-9B06873D764E531> ; data: {
    fullname = nil;
    identifier = nil;
})

Lo extraño es que la relación se establece correctamente (incluso si se mira en la base de datos sqlite, y todo se ve bien allí) pero no estoy contento con que algo claramente esté mal en el código RestKit, y parece que tiene algo que ver con El mapeo de usuario falso que creo en el código anterior (está vacío, ya que no hay nada que asignar en la matriz de ID).

He probado alternativas, por ejemplo, cuando agrego un mapeo de ruta de acceso clave:

[userMapping mapKeyPath:@"" toAttribute:@"identifier"];

Se queja, obviamente porque la ruta de acceso está vacía.

2012-10-24 09:24:11.735 Test[35399:14003] !! Uncaught exception !!
[<__NSCFString 0xa57f460> valueForUndefinedKey:]: this class is not key value coding-compliant for the key .

Y si trato de usar lo real.User cartografía

[groupMapping hasMany:@"members" withMapping:[[RKObjectManager sharedManager].mappingProvider objectMappingForKeyPath:@"users"]];

Obtuve el siguiente error

2012-10-24 09:52:49.973 Test[35799:18403] !! Uncaught exception !!
[<__NSCFString 0xa56e9a0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key _id.
2012-10-24 09:52:49.973 Test[35799:18403] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0xa56e9a0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key _id.'

Parece que RestKit está tratando de asignar las cadenas de ID en la matriz memberIDs aUser Objetos, lo que no tiene ningún sentido. He visto ejemplos en los que la matriz de relaciones es una lista de diccionarios con claves (por ejemplo, llamadaid) con el ID de referencia al otro objeto, por ejemplo:

{"groups":
  [{"name": "John's group", "_id": "a",
    "members": [
      {"_id": "1"},
      {"_id": "2"}
     ]
   ...
  ]
}

Pero no quiero cambiar mi JSON de esa manera (además, espero que RestKit sea lo suficientemente flexible como para apoyar la otra forma).

¿Alguien sabe cuál es la forma correcta de hacer este tipo de mapeo de relaciones en RestKit?

Actualizar

Terminé modificando la interfaz REST para enviar una lista de diccionarios que contenían las ID de objeto de usuario (como en el último ejemplo anterior), y conseguí que funcionara. Aún no estoy completamente satisfecho con la configuración, pero el código ahora parece

RKObjectManager* objectManager = [RKObjectManager sharedManager];
RKManagedObjectMapping* groupMapping = [RKManagedObjectMapping mappingForClass:[Group class] inManagedObjectStore:objectManager.objectStore];
groupMapping.primaryKeyAttribute = @"identifier";
[groupMapping mapKeyPath:@"_id" toAttribute:@"identifier"];
[groupMapping mapKeyPath:@"name" toAttribute:@"name"];
[groupMapping mapKeyPath:@"members._id" toAttribute:@"memberIDs"];
[objectManager.mappingProvider setMapping:groupMapping forKeyPath:@"groups"];

// Create an empty user mapping to handle the relationship mapping
RKManagedObjectMapping* userMapping = [RKManagedObjectMapping mappingForClass:[User class] inManagedObjectStore:objectManager.objectStore];
userMapping.primaryKeyAttribute = @"identifier";
[userMapping mapKeyPath:@"_id" toAttribute:@"identifier"];

[groupMapping hasMany:@"members" withMapping:userMapping];
[groupMapping connectRelationship:@"members" withObjectForPrimaryKeyAttribute:@"memberIDs"];

RKObjectRouter* router = objectManager.router;

[router routeClass:[Group class] toResourcePath:@"/rest/groups/:identifier"];
[router routeClass:[Group class] toResourcePath:@"/rest/groups/" forMethod:RKRequestMethodPOST];
// Assume url is properly defined to point to the right path...
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:url usingBlock:^(RKObjectLoader *loader) {}];

Por si acaso esto ayuda a alguien más en una situación similar. Es posible que todavía haya algunos problemas con el enfoque que he tomado, pero hasta ahora todo va bien (incluso se maneja fuera de servicio la carga, lo que es bueno): todavía me encantaría saber de alguien si hay una respuesta a mi pregunta original.

Respuestas a la pregunta(1)

Su respuesta a la pregunta