1
votes

I am attempting to use a NSManagedObject as a response class in my requests, but I have relationships that I need saturated as well that I do not want managed because they change far more frequently. I have attempted to use just plain NSObject's along with transient relationships to NSManagedObject's, but either approach ends up with empty relationships (the transient or NSObjects don't get saturated).

Here is the object I want saturated from the request and stored in SQLite:

@interface Car : NSManagedObject

@property (nonatomic, retain) NSString *brand
@property (nonatomic, retain) MLocation *location //don't want persisted

@end

Here is the object I don't want persisted, but saturated:

//I have tried this with NSObject and NSManagedObject
@interface MLocation : NSObject

@property (nonatomic, assign) double latitude;
@property (nonatomic, assign) double longitude;

@end

Here is the response descriptor:

[manager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:self.buildCarMapping
                                                                            method:RKRequestMethodGET
                                                                       pathPattern:@"/v1/cars/near/:latitude/:longitude"
                                                                           keyPath:nil
                                                                       statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)] ];

Here is the object mapping:

- (RKObjectMapping *)buildCarMapping {
    RKEntityMapping *carMapping = [RKEntityMapping mappingForEntityForName:@"Car" inManagedObjectStore:self.managedObjectStore];
    [carMapping addAttributeMappingsFromDictionary:@{
            @"brand" : @"brand"
    }];

    [carMapping addRelationshipMappingWithSourceKeyPath:@"location" mapping:self.buildLocationMapping];
    return carMapping;
}

//I have tried this with NSObject and a transient NSManagedObject relationship
- (RKObjectMapping *)buildLocationMapping {
    RKObjectMapping *locationMapping = [RKObjectMapping mappingForClass:[MLocation class]];
    [locationMapping addAttributeMappingsFromDictionary:@{
            @"longitude": @"longitude",
            @"latitude": @"latitude"
    }];
    return locationMapping;
}

Here is an example response:

{
  "brand": "Chevy",
  "location": {  //This is ignored by RestKit using my mappings
    "latitude": 42.8,
    "longitude": -98.6
  }
}
1

1 Answers

0
votes

I don't think there is going to be a way to do that because the managed objects are created on a background thread and the only way to get them back to you is by destroying those instances (with your temporary data) and generating the corresponding instances from the persistent data on the main thread.

Possibly if you create and execute the mapping operation yourself on the current thread it could work, but there would be a number of other requirements for you to manage / issues to deal with.

I would think about using 2 response descriptors. The first, like you have, would process the Core Data related content into the persistent store. The second would be used to create the plain (temporary) object, in an appropriate instance hierarchy, which contained the unique identifiers (as required) such that you could fetch the associated managed objects when you need them. You wouldn't have direct relationships, but you would have all the information you needed.