2012-06-09 22 views
5

Estoy utilizando RestKit 0.10.1 con Core Data en un destino de implementación iOS 5.0 para construir una aplicación que interactúe con una API RESTFul personalizada. Dado que la conectividad fuera de línea es importante, estoy manteniendo un caché de los datos del usuario en una base de datos CoreData local en el dispositivo.RestKit + CoreData: ¿Cómo guardar un objeto localmente solo después de que el guardado remoto se haya realizado correctamente?

Ahora, RestKit es bastante impresionante y ha sido bastante fácil configurar un RKFetchResultsTableController para mostrar y conservar fácilmente mis datos. Sin embargo, hay un comportamiento de RestKit que no parece ideal y que no puedo descifrar cómo cambiar.

Tengo un modelo llamado 'Grabación'. Para crear una nueva grabación, estoy haciendo lo siguiente:

Recording *r = [NSEntityDescription insertNewObjectForEntityForName:@"Recording" inManagedObjectContext:[[RKObjectManager sharedManager].objectStore managedObjectContextForCurrentThread]]; 

r.name = newName; 

[[RKObjectManager sharedManager] sendObject:r toResourcePath:@"/recordings" usingBlock:^(RKObjectLoader *loader){ 
     loader.delegate = self; 
     loader.method = RKRequestMethodPOST; 
     loader.serializationMIMEType = RKMIMETypeJSON; 

     loader.serializationMapping = [RKObjectMapping serializationMappingUsingBlock:^(RKObjectMapping *serializationMapping){ 
      [serializationMapping mapAttributes:@"name", nil]; 

     }]; 

     RBMappingProvider *mappings = (RBMappingProvider *)[[RKObjectManager sharedManager] mappingProvider]; 
     loader.objectMapping = [mappings recordingObjectMapping]; 

    }]; 

Esto crea una nueva entidad de tipo 'Grabación' y luego envía la entidad al servidor en una solicitud POST. En un caso de éxito, esto funciona genial.

Sin embargo, el problema es que el servidor algunas veces rechaza estas crea legítimamente. Lo que encuentro en estas situaciones es que ya hay una copia local de la entidad en la base de datos Core Data con un id de 0 (el id es la clave principal que el servidor establece).

La única manera de eliminar la entidad local es forzar una actualización de los datos locales del servidor.

¿Hay alguna forma de persistir el objeto localmente solo una vez que el servidor responde con un 2xx? Alternativamente, ¿hay alguna manera de deshacer los cambios si el servidor responde con algo que no sea un 2xx?

Gracias,

+0

Fwiw, la creación de la entidad con la de grabación * r = [objeto de grabación] como se prescribe en la documentación RestKit no cambia el comportamiento en absoluto. – apurva

+0

¿No tiene un método de devolución de llamada en RK con la respuesta del servidor? Mantenga una referencia al objeto y elimínelo si la carga fue rechazada. – Mundi

+0

@mundi Ese es un enfoque, e incluso puede ser el más deseable. Sin embargo, me preguntaba si era posible persistir en el estado local solo después de que el servidor aceptara la carga útil. Esto daría como resultado un código mucho menos redundante. – apurva

Respuesta

0

Desafortunadamente, debido a la grabación es un NSManagedObject, incluso su instancia temporal debe ser insertado en el contexto de objeto gestionado. La solución de @Mundi de mantener la referencia y eliminarla del contexto después del error es la solución que usaría. Un poco de código adicional gana una actualización completa del servidor.

Actualizar a 0.20.x lo hará más fácil. Los bloques de éxito y falla que se utilizan al enviar una solicitud hacen que sea muy fácil mantener esta referencia y eliminarla en caso de error. Por ejemplo:

[_objectManager postObject:aMessage 
         path:@"message" 
       parameters:parameters 
        success:^(RKObjectRequestOperation * operation, RKMappingResult * mappingResult){ 
        // Success code here 
        } 
        failure:^(RKObjectRequestOperation * operation, NSError * error){ 
        [_managedObjectContext deleteObject:aMessage]; 
        [_managedObjectContext save:nil]; 
        }]; 
Cuestiones relacionadas