[RestKit 0.20] Update d'un objet stocké dans CoreData
tplessis
Membre
Bonjour,
J'utilise RestKit pour mapper mes objets entre mon webservice REST et mon appli iOs. Je met en cache mes données dans une base sqlite via la couche CoreData. Tout fonctionne lors de la création de mon utilisateur, idem pour l'identification. Vient ensuite le moment de mettre à jour le compte de l'utilisateur et là , impossible de mettre a jour les données dans CoreData, rien ne se passe.... en revanche aucun probleme côté serveur, les données sont bien envoyées et mises à jour.
En gros la synchro ne se fait pas côté client, dans la couche CoreData.
Voici mon objet BUser :
Et voici comment j'envoi mon objet BUser via RestKit :
Et pour finir, l'initialisation de RestKit et le mapping que j'utilise :
Je pense qu'il s'agit peut etre d'un probleme avec le managedContext de CoreData qui n'est plus le meme au moment ou j'envoi mes données. Mais je n'arrive pas a savoir pourquoi....
Des idées?
Thomas
J'utilise RestKit pour mapper mes objets entre mon webservice REST et mon appli iOs. Je met en cache mes données dans une base sqlite via la couche CoreData. Tout fonctionne lors de la création de mon utilisateur, idem pour l'identification. Vient ensuite le moment de mettre à jour le compte de l'utilisateur et là , impossible de mettre a jour les données dans CoreData, rien ne se passe.... en revanche aucun probleme côté serveur, les données sont bien envoyées et mises à jour.
En gros la synchro ne se fait pas côté client, dans la couche CoreData.
Voici mon objet BUser :
<br />
@interface BUser : NSManagedObject<br />
@property (nonatomic, retain) NSNumber *userID;<br />
@property (nonatomic, retain) NSString *name;<br />
@property (nonatomic, retain) NSString *address;<br />
@property (nonatomic, retain) NSString *password;<br />
@property (nonatomic, retain) NSString *token;<br />
@property (nonatomic, retain) NSString *phone;<br />
@property (nonatomic, retain) NSString *email;<br />
@property BOOL *isActivated;<br />
@property BOOL *hasContactsRights;<br />
@property (nonatomic, retain) NSString *city;<br />
@property (nonatomic, retain) NSString *activationCode;<br />
+ (BUser*) sharedInstance;<br />
@end<br />
<br />
@implementation BUser<br />
@synthesize userID;<br />
@synthesize name;<br />
@synthesize address;<br />
@synthesize password;<br />
@synthesize token;<br />
@synthesize phone;<br />
@synthesize email;<br />
@synthesize isActivated;<br />
@synthesize hasContactsRights;<br />
@synthesize city;<br />
@synthesize activationCode;<br />
+ (BUser*) sharedInstance {<br />
static BUser *myInstance = nil;<br />
if (myInstance == nil) {<br />
myInstance = [[[self class] alloc] init];<br />
}<br />
return myInstance;<br />
}<br />
@end<br />
Et voici comment j'envoi mon objet BUser via RestKit :
<br />
RKManagedObjectRequestOperation *operation = [[RKObjectManager sharedManager] appropriateObjectRequestOperationWithObject:[BUser sharedInstance] method:RKRequestMethodPUT path:[NSString stringWithFormat:@"/user/%@", [BUser sharedInstance].userID] parameters:authParams];<br />
operation.targetObject = [BUser sharedInstance];<br />
operation.managedObjectContext = [RKObjectManager sharedManager].managedObjectStore.mainQueueManagedObjectContext;<br />
operation.managedObjectCache = [RKObjectManager sharedManager].managedObjectStore.managedObjectCache;<br />
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {<br />
BUser *user = [result firstObject];<br />
NSLog(@"Mapped the article: %@", user);<br />
} failure:^(RKObjectRequestOperation *operation, NSError *error) {<br />
NSLog(@"Failed with error: %@", [error localizedDescription]);<br />
}];<br />
NSOperationQueue *operationQueue = [NSOperationQueue new];<br />
[operationQueue addOperation:operation];<br />
Et pour finir, l'initialisation de RestKit et le mapping que j'utilise :
<br />
// Configure core data to works with RESTkit<br />
NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];<br />
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];<br />
NSString *path = [RKApplicationDataDirectory() stringByAppendingPathComponent:BAOBAB_DB_NAME];<br />
[managedObjectStore addSQLitePersistentStoreAtPath:path fromSeedDatabaseAtPath:nil withConfiguration:nil options:nil error:nil];<br />
[managedObjectStore createManagedObjectContexts];<br />
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:REST_SERVER_URL]];<br />
manager.managedObjectStore = managedObjectStore;<br />
[managedObjectStore.persistentStoreManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];<br />
//managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];<br />
<br />
// Object Mapping<br />
RKObjectMapping *userRequestMapping = [RKObjectMapping requestMapping];<br />
[userRequestMapping addAttributeMappingsFromDictionary:@{<br />
@"userID" : @"id",<br />
@"name" : @"name",<br />
@"phone" : @"phone",<br />
@"email" : @"email",<br />
@"city" : @"city",<br />
@"address" : @"address",<br />
@"password" : @"password"<br />
}];<br />
RKEntityMapping* userResponseMapping = [RKEntityMapping mappingForEntityForName:@"BUser" inManagedObjectStore:manager.managedObjectStore];<br />
[userResponseMapping addAttributeMappingsFromDictionary:@{<br />
@"id" : @"userID",<br />
@"name" : @"name",<br />
@"address" : @"address",<br />
@"password" : @"password",<br />
@"phone" : @"phone",<br />
@"email" : @"email",<br />
@"token" : @"token",<br />
@"is_activated" : @"isActivated",<br />
@"has_contacts_rights" : @"hasContactsRights",<br />
@"city" : @"city",<br />
@"activation_code" : @"activationCode"<br />
}];<br />
userResponseMapping.identificationAttributes = @[@"userID"];<br />
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); // Anything in 2xx<br />
<br />
RKRequestDescriptor *userRequestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:userRequestMapping objectClass:[BUser class] rootKeyPath:@"user"];<br />
RKResponseDescriptor *userResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:userResponseMapping pathPattern:@"/user" keyPath:nil statusCodes:statusCodes];<br />
RKResponseDescriptor *userLoadResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:userResponseMapping pathPattern:@"/user/:userID" keyPath:nil statusCodes:statusCodes];<br />
<br />
// Mapping errors<br />
NSIndexSet *statusCodesErrors = RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError);<br />
RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];<br />
[errorMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil toKeyPath:@"errorMessage"]];<br />
RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:errorMapping pathPattern:nil keyPath:@"errors" statusCodes:statusCodesErrors];<br />
<br />
[manager addRequestDescriptor:userRequestDescriptor];<br />
[manager addResponseDescriptor:userResponseDescriptor];<br />
[manager addResponseDescriptor:userLoadResponseDescriptor];<br />
[manager addResponseDescriptor:errorDescriptor];<br />
Je pense qu'il s'agit peut etre d'un probleme avec le managedContext de CoreData qui n'est plus le meme au moment ou j'envoi mes données. Mais je n'arrive pas a savoir pourquoi....
Des idées?
Thomas
Mots clés:
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
A priori, si ce sont des données à jour qui sont envoyées au serveur, alors les données sont forcément à jour dans le MOC (Managed Object Context), puisque c'est là que RESTKit vient les chercher.
Un manière de t'en assurer est d'ouvrir la base SQLite avec un éditeur. Il faudra mettre à jour le fichier en envoyant un -save au MOC.
En espérant que cela puisse t'aider.
P.S.: Merci de faire attention dans quelle section tu postes, ça n'a rien à faire dans Vos projets d'applications.
PS: Pardon pour le mauvais forum, je ferais gaffe la prochaine fois. /wink.png' class='bbc_emoticon' alt=';)' />
Quand tu fais une sous classe de NSManagedObject tu ne dois pas mettre @synthesize pour tes variables d'instance qui sont sauvegardées dans CoreData mais plutôt @dynamic. NSManagedObject s'occupera au runtime de "créer" les setters qui vont bien pour sauvegarder en base.
En espérant que ça corrige ton problème /smile.png' class='bbc_emoticon' alt=':)' />
Effectivement, ça explique carrément le problème observé, mais pas pourquoi ça apparaà®trait dans la base SQLite, alors.