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 :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 
@interface BUser : NSManagedObject
@property (nonatomic, retain) NSNumber *userID;
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *address;
@property (nonatomic, retain) NSString *password;
@property (nonatomic, retain) NSString *token;
@property (nonatomic, retain) NSString *phone;
@property (nonatomic, retain) NSString *email;
@property BOOL *isActivated;
@property BOOL *hasContactsRights;
@property (nonatomic, retain) NSString *city;
@property (nonatomic, retain) NSString *activationCode;
+ (BUser*) sharedInstance;
@end
 
@implementation BUser
@synthesize userID;
@synthesize name;
@synthesize address;
@synthesize password;
@synthesize token;
@synthesize phone;
@synthesize email;
@synthesize isActivated;
@synthesize hasContactsRights;
@synthesize city;
@synthesize activationCode;
+ (BUser*) sharedInstance {
    static BUser *myInstance = nil;
    if (myInstance == nil) {
        myInstance = [[[self class] alloc] init];
    }
    return myInstance;
}
@end
Et voici comment j'envoi mon objet BUser via RestKit :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
 
RKManagedObjectRequestOperation *operation = [[RKObjectManager sharedManager] appropriateObjectRequestOperationWithObject:[BUser sharedInstance] method:RKRequestMethodPUT path:[NSString stringWithFormat:@"/user/%@", [BUser sharedInstance].userID] parameters:authParams];
        operation.targetObject = [BUser sharedInstance];
        operation.managedObjectContext = [RKObjectManager sharedManager].managedObjectStore.mainQueueManagedObjectContext;
        operation.managedObjectCache = [RKObjectManager sharedManager].managedObjectStore.managedObjectCache;
        [operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
            BUser *user = [result firstObject];
            NSLog(@"Mapped the article: %@", user);
        } failure:^(RKObjectRequestOperation *operation, NSError *error) {
            NSLog(@"Failed with error: %@", [error localizedDescription]);
        }];
        NSOperationQueue *operationQueue = [NSOperationQueue new];
        [operationQueue addOperation:operation];
Et pour finir, l'initialisation de RestKit et le mapping que j'utilise :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 
// Configure core data to works with RESTkit
    NSManagedObjectModel *managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
    RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
    NSString *path = [RKApplicationDataDirectory() stringByAppendingPathComponent:BAOBAB_DB_NAME];
    [managedObjectStore addSQLitePersistentStoreAtPath:path fromSeedDatabaseAtPath:nil withConfiguration:nil options:nil error:nil];
    [managedObjectStore createManagedObjectContexts];
    RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:REST_SERVER_URL]];
    manager.managedObjectStore = managedObjectStore;
    [managedObjectStore.persistentStoreManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
    //managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
 
    // Object Mapping
    RKObjectMapping *userRequestMapping = [RKObjectMapping requestMapping];
    [userRequestMapping addAttributeMappingsFromDictionary:@{
     @"userID" : @"id",
     @"name" : @"name",
     @"phone" : @"phone",
     @"email" : @"email",
     @"city" : @"city",
     @"address" : @"address",
     @"password" : @"password"
     }];
    RKEntityMapping* userResponseMapping = [RKEntityMapping mappingForEntityForName:@"BUser" inManagedObjectStore:manager.managedObjectStore];
    [userResponseMapping addAttributeMappingsFromDictionary:@{
     @"id" : @"userID",
     @"name" : @"name",
     @"address" : @"address",
     @"password" : @"password",
     @"phone" : @"phone",
     @"email" : @"email",
     @"token" : @"token",
     @"is_activated" : @"isActivated",
     @"has_contacts_rights" : @"hasContactsRights",
     @"city" : @"city",
     @"activation_code" : @"activationCode"
     }];
    userResponseMapping.identificationAttributes = @[@"userID"];
    NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); // Anything in 2xx
 
    RKRequestDescriptor *userRequestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:userRequestMapping objectClass:[BUser class] rootKeyPath:@"user"];
    RKResponseDescriptor *userResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:userResponseMapping pathPattern:@"/user" keyPath:nil statusCodes:statusCodes];
    RKResponseDescriptor *userLoadResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:userResponseMapping pathPattern:@"/user/:userID" keyPath:nil statusCodes:statusCodes];
 
    // Mapping errors
    NSIndexSet *statusCodesErrors = RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError);
    RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];
    [errorMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil toKeyPath:@"errorMessage"]];
    RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:errorMapping pathPattern:nil keyPath:@"errors" statusCodes:statusCodesErrors];
 
    [manager addRequestDescriptor:userRequestDescriptor];
    [manager addResponseDescriptor:userResponseDescriptor];
    [manager addResponseDescriptor:userLoadResponseDescriptor];
    [manager addResponseDescriptor:errorDescriptor];
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