Search code examples
ioscore-datarestkit

Restkit-Failed to call designated initializer on NSManagedObject class


I am using Restkit for a class that Extends NSManagedObject. I am aware that rest kit itself has functionality to save to core data from network fetch. However, I cannot use that functionality due to the following reasons:

  • My application will be fetching data from sockets as well as from rest kit , so I would want a centralised location for saving/deleting logic.
  • My server does not confirm to rest protocols, so many times I have to send a POST request even when I really want to delete something in server.

So What I wanted to do was have my Model classes extend nsmanaged object, and save it when I want to. But I get this error:

CoreData: error: Failed to call designated initializer on NSManagedObject class

Is there a way to go around this ?

I am fetching from server like this :

@implementation API_Login
+(void)performLoginWithEmail:(NSString*)email
                withPassword:(NSString*)password
                     success:(void (^)(Token* user) )success
                     failure:failureblock failure{

    RKObjectManager * objectManager = [APIHelper getRestObjectManager];
    RKObjectMapping *tokenMapping = [RKObjectMapping mappingForClass:[Token class]];

//add mapping for token
    [tokenMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil toKeyPath:@"token"]];
    RKResponseDescriptor *responseDescriptor =
    [RKResponseDescriptor responseDescriptorWithMapping:tokenMapping
                                                 method:RKRequestMethodGET
                                            pathPattern:nil
                                                keyPath:nil
                                            statusCodes:[NSIndexSet indexSetWithIndex:200]];

    [objectManager addResponseDescriptor:responseDescriptor];


//    add mapping for error
    RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[Error class]];
    [errorMapping addAttributeMappingsFromDictionary:@{@"message":@"message",@"badRequest":@"badRequest"}];
    RKResponseDescriptor *errorResponseDescriptor =
    [RKResponseDescriptor responseDescriptorWithMapping:errorMapping
                                                 method:RKRequestMethodGET
                                            pathPattern:nil
                                                keyPath:nil
                                            statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError)];

    [objectManager addResponseDescriptor:errorResponseDescriptor];



    NSDictionary *queryParams =  @{@"email" : email,
                                   @"password" : password,
                                   };

    [objectManager postObject:nil
                         path:@"/users/api/login"
                   parameters:queryParams
                      success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {

                          Token* token =  (Token*)[mappingResult firstObject] ;
//                          [AppDelegateHandle setToken:token];
                          success(token);
                      } failure:^(RKObjectRequestOperation *operation, NSError *error) {
                          NSArray* e = [[error userInfo] objectForKey:RKObjectMapperErrorObjectsKey];
                          Error *err = (Error*)[e objectAtIndex:0];
                          NSLog(@"%@",[err.badRequest allValues] );
                          failure(operation,error);
                      }];


}
@end

My Token class looks like:

@interface Token : NSManagedObject
@property NSString* token;
@end

and my api response looks like :

{
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjEsImlzcyI6Imh0dHA6XC9cL3JlbWluZGVyLmRldlwvdXNlcnNcL2FwaVwvbG9naW4iLCJpYXQiOjE0Njg1OTM3NjYsImV4cCI6MTQ2OTE5Mzc2NiwibmJmIjoxNDY4NTkzNzY2LCJqdGkiOiIxMDc3ZjBhY2ViYTFjOWZjZWNhYjkyMzYyOTA0ZmI4NSJ9.I6FHJLCCHr3EHQa8HgaDqxQMjF1HVyA5AymPjvBGDrM"
}

When I change Token to extend NSObject instead of NSManagedObject , everything works fine. What could the problem be ?


Solution

  • This happens because you're using RKObjectMapping instead of RKEntityMapping which is required if you're using a subclass of NSManagedObject.

    You can't use a subclass of NSManagedObject if you aren't going to add it directly into a context.

    If your request simply has a token then I wouldn't bother with RestKit probably, but in the general case I'd map to NSDictionary with the keys being the same as your managed object classes and then when you want to create your managed objects you can do so and 'import' the data to them with setValuesForKeysWithDictionary:.