Estoy queriendo usar RestKit para una aplicación que necesita funcionar tanto con conexión como sin conexión.Soporte en línea y fuera de línea para aplicaciones de RestKit iOS
Es posible que no esté entendiendo cómo funciona RestKit, pero pensé que esto era (bastante) fácil de implementar.
En una prueba de marcar iOS puse cosas de la siguiente manera:
// setup the client
NSString* URL = @"http://10.211.55.5:3000/api";
RKClient* client = [RKClient clientWithBaseURL:URL];
client.username = @"[email protected]";
client.password = @"password";
// setup caching
client.cachePolicy = RKRequestCachePolicyLoadIfOffline | RKRequestCachePolicyLoadOnError | RKRequestCachePolicyTimeout;
client.requestCache.storagePolicy = RKRequestCacheStoragePolicyPermanently;
// setup managed object store
RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:URL];
RKManagedObjectStore* objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@"RestKitCoreDataTest.sqlite"];
// connect my cache implementation
MyCache* cache = [[MyCache alloc] init];
objectStore.managedObjectCache = cache;
objectManager.objectStore = objectStore;
// setup mapping
RKManagedObjectMapping* userMapping = [RKManagedObjectMapping mappingForClass:[User class]];
[userMapping mapKeyPath:@"id" toAttribute:@"identifier"];
[userMapping mapKeyPath:@"email" toAttribute:@"email"];
[userMapping mapKeyPath:@"firstname" toAttribute:@"firstname"];
[userMapping mapKeyPath:@"surname" toAttribute:@"surname"];
userMapping.primaryKeyAttribute = @"identifier";
[objectManager.mappingProvider setMapping:userMapping forKeyPath:@""];
// setup routes
RKObjectRouter* router = [objectManager router];
[router routeClass:[User class] toResourcePath:@"https://stackoverflow.com/users/:identifier"];
el objeto de usuario se implementa como necesario para la compatibilidad CoreData:
@interface User : NSManagedObject
@property (nonatomic, retain) NSNumber * identifier;
@property (nonatomic, retain) NSString * email;
@property (nonatomic, retain) NSString * firstname;
@property (nonatomic, retain) NSString * surname;
@end
@implementation User
@dynamic identifier;
@dynamic email;
@dynamic firstname;
@dynamic surname;
@end
Aquí es MyCache. Tenga en cuenta que no me molesto en comprobar resourcePath
ya que esto es solo para probar cosas, y tengo una ruta de todos modos.
@implementation MyCache
- (NSArray*)fetchRequestsForResourcePath:(NSString*)resourcePath
{
NSFetchRequest* fetchRequest = [User fetchRequest];
return [NSArray arrayWithObject:fetchRequest];
}
-(BOOL)shouldDeleteOrphanedObject:(NSManagedObject *)managedObject
{
return true;
}
@end
continuación hago una llamada al servidor para obtener el usuario con id 123, en la ruta "/ api/users/123":
User* user = [User object];
user.identifier = [NSNumber numberWithInt:123];
RKObjectManager* manager = [RKObjectManager sharedManager];
[manager getObject:user delegate:self];
Esto funciona bien. Pero cuando desconecto el wifi de mi Mac, el código anterior no recupera al usuario de la base de datos sqlite.
me sale el siguiente error en lugar de objectLoader:didFailWithError
del delegado:
2012-03-01 11:44:09.402 RestKitCoreDataTest[1989:fb03] error: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0x6b89aa0 {NSErrorFailingURLStringKey=http://10.211.55.5:3000/api/users/123, NSErrorFailingURLKey=http://10.211.55.5:3000/api/users/123, NSLocalizedDescription=The request timed out., NSUnderlyingError=0x6b81ac0 "The request timed out."}
pensé que en virtud de que se especifica que la memoria caché se debe utilizar cuando hay un tiempo de espera, con: "RKRequestCachePolicyTimeout", que hubiera esperado el usuario que se recuperará de la memoria caché local.
La memoria caché contiene un registro de usuario con ID 123 - en la tabla ZUSER, con 123 en la columna ZIDENTIFIER.
¿Hay algún paso que me falta para que esto funcione? ¿Quizás otro método delegado que necesita ser manejado, o se llama, cuando la caché es golpeada después del tiempo de espera ? ¿O estoy tratando de hacer algo que no necesariamente es algo que obtendría "de fábrica" con RestKit?
Saludos.
Hola , Estoy tratando de hacer lo mismo con RestKit 0.20.1 - ¿Alguna actualización sobre esto? ¿conseguiste que esto funcionara? La respuesta que marcó no parece responder a su pregunta ... ¡Gracias! – Diego
Revisé la respuesta a continuación como correcta porque tomé la sugerencia de Julian de utilizar una clase de alcance para verificar si estaba en línea o fuera de línea. Más tarde terminé usando RestKit para comunicaciones en línea, y CoreData para almacenamiento fuera de línea. – dbarros
¡Bien, gracias! Creo que intentaré centralizar esto en el delegado de la aplicación, aunque para hacerlo creo que es mejor si creo una cola de operación HTTP que luego analizo cada vez que se necesita sincronización (posiblemente periódicamente). – Diego