Using Keys as Values in RestKit - ios

So, we have an API that spits out:
{
"2013-12-13": [subobject1, subobject2, subobjects3],
"2013-12-14": [subobject4, subobject5],
...
}
I'm not sure, though, how to parse things in RestKit where the key changes dynamically.
I'd probably like to parse it into a list of objects that have a date, and the list of subobjects.
Any thoughts?

You need to create a mapping something like:
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[XXX class]];
[mapping addAttributeMappingFromKeyOfRepresentationToAttribute:#"date"];
[mapping addAttributeMappingsFromDictionary:#{
#"(date)": #"values"
}];
Where your XXX class has properties for date (NSDate) and values (NSArray).

Related

How to Rectify the Relationship Fault in CoreData While parsing RESTKIT?

I want to Store the EY_ConnectionUsage Entity value to the EY_Connection entity Cell.I have Added two Entities with Attributes and Created Relationship with name usageData.But this Shows error "<'usageData' Relationship Fault>".This is a Method I wrote to map the RESTKIT value to CoreData.
DataAccessHandler.m
+(void)createConnectionMappingWithStore:(RKManagedObjectStore *)managedObjectStore saveInDelegate:(AppDelegate *)appDelegate{
NSLog(#"appdele==>>%#",appDelegate);
RKEntityMapping *connectionMapping = [RKEntityMapping mappingForEntityForName:#"EY_Connections" inManagedObjectStore:managedObjectStore];
connectionMapping.identificationAttributes = #[#"connectionNumber"];
[connectionMapping addAttributeMappingsFromDictionary:#{ #"ServiceNo" : #"connectionServiceNumber", #"Name" : #"connectionName", #"Region" : #"connectionRegion", #"Phase" : #"connectionPhase",
#"Circle" : #"connectionCircle", #"Section" : #"connectionSection", #"Load" : #"connectionLoad",
#"Distribution" : #"connectionDistribution", #"MeterNo" : #"connectionMeterNumber", #"ConnectionNumber" : #"connectionNumber", #"Address" : #"connectionAddress", #"ServiceStatus" : #"connectionStatus"}];
RKEntityMapping *connectionUsageMapping = [RKEntityMapping mappingForEntityForName:#"EY_ConnectionUsage" inManagedObjectStore:managedObjectStore];
connectionUsageMapping.identificationAttributes = #[#"usageAssessmentDate"];
[connectionUsageMapping addAttributeMappingsFromDictionary:#{ #"assessment_date" : #"usageAssessmentDate", #"reading" : #"usageReading", #"units" : #"usageUnits", #"amount" : #"usageAmount",
#"payment_date" : #"usagePaymentDate", #"status" : #"usageStatus"}];
[connectionMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"usage" toKeyPath:#"usageData" withMapping:connectionUsageMapping]];
RKResponseDescriptor *articleListResponseDescriptor =
[RKResponseDescriptor responseDescriptorWithMapping:connectionMapping
method:RKRequestMethodGET
pathPattern:#"user_history/consumer/data.json"
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)
];
[appDelegate createObjectManagerForurl:#"http://sciflare.com/energyly/api/" andAddResponseDescriptor:articleListResponseDescriptor];
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
}
<'usageData' Relationship Fault>
This means that the relationship data hasn't been loaded yet, because you haven't tried to use it. Logging the object isn't enough to load the data. The whole point of the faulting system is to prevent too much data being loaded into memory at the same time.
So, basically, it isn't a problem that it's a fault. When you try to use it the data will be populated and everything will be fine.
CoreData says that 'load only needed data'. If we are trying to fetch unwanted data then coredata shows 'FAULT'.
Foe more detail please go through CoreData Fault

RestKit: How to POST a NSManagedObject as JSON without any nesting attributes?

This should be a really easy one, but sadly I haven't found any answer...
What RestKit mapped my object to:
request.body={"user":{"pass":"1234","id":0,"login":"awesome_guy","tier":0}}
What I really want:
{"pass":"1234","id":0,"login":"awesome_guy","tier":0}
Just without the object name "user".
If you have dealt with this issue, it'll take you 5 seconds to answer. If you haven't used RestKit. You do not know the answer. I'm attaching my code anyway:
User Object Mapping:
/* ===========================
* ====User Object Mapping====
* ==========================*/
RKEntityMapping* userObjectMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([User class]) inManagedObjectStore:objectManager.managedObjectStore];
NSDictionary *userObjectMappingDict = #{
#"id":#"id",
#"login":#"login",
#"firstName":#"firstName",
#"lastName":#"lastName",
#"phoneNumber":#"phoneNumber",
#"email":#"email",
#"tier":#"tier",
#"sessionId":#"sessionId",
#"pass":#"password"
};
userObjectMapping.identificationAttributes = #[#"id"];
[userObjectMapping addAttributeMappingsFromDictionary:userObjectMappingDict];
RKEntityMapping* userBusinessMapping = [RKEntityMapping mappingForEntityForName:#"Business" inManagedObjectStore:objectManager.managedObjectStore];
[userBusinessMapping addAttributeMappingsFromDictionary:#{#"business":#"id"}]; // Nil Key path
[userObjectMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:#"business" withMapping:userBusinessMapping]];
You should have an instance of RKRequestDescriptor that you haven't shown. It's created with requestDescriptorWithMapping:objectClass:rootKeyPath:. You have the root key path set to #"user" and you should set it to nil.

Multiple RKRelationshipMapping with same toKeyPath

I have a problem using multiple RKRelationshipMappings with same toKeyPath (destinationKeyPath).
I have had success with using one RKRelationshipMapping to one toKeyPath but I'm unable to attach a second RKRelationshipMappings with the same toKeyPath.
Code with one RKRelationshipMapping that works:
RKObjectMapping *someObjectRequestMapping = [RKObjectMapping requestMapping];
[someObjectRequestMapping addAttributeMappingsFromDictionary:#{#"prop1" : #"prop_1", #"prop2" : #"prop_2"}];
RKObjectMapping *firstSubObjectMapping = [RKObjectMapping requestMapping];
[firstSubObjectMapping addAttributeMappingsFromDictionary:#{#"subProp1" : #"sub_prop1", #"subProp2" : #"sub_prop2"}];
[someObjectRequestMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"prop3"
toKeyPath:#"prop_3"
withMapping:firstSubObjectMapping];
However, if i want to add another RKRelationshipMapping to "someObjectRequestMapping" with the same toKeyPath ("prop_3") the RestKit fails with error:
*'NSInternalInconsistencyException', reason: 'Unable to add mapping for keyPath invites_attributes, one already exists...'*
Code with two RKRelationshipMappings that fails:
RKObjectMapping *someObjectRequestMapping = [RKObjectMapping requestMapping];
[someObjectRequestMapping addAttributeMappingsFromDictionary:#{#"prop1" : #"prop_1", #"prop2" : #"prop_2"}];
RKObjectMapping *firstSubObjectMapping = [RKObjectMapping requestMapping];
[firstSubObjectMapping addAttributeMappingsFromDictionary:#{#"subProp1" : #"sub_prop1", #"subProp2" : #"sub_prop2"}];
RKObjectMapping *secondSubObjectMapping = [RKObjectMapping requestMapping];
[secondSubObjectMapping addAttributeMappingsFromDictionary:#{#"subProp2" : #"sub_prop2", #"subProp3" : #"sub_prop3"}];
[someObjectRequestMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"prop3"
toKeyPath:#"prop_3"
withMapping:firstSubObjectMapping];
[someObjectRequestMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"prop4"
toKeyPath:#"prop_3"
withMapping:secondSubObjectMapping];
The mapping is used in RKRequestDescriptor.
Any help would be greatly appreciated.
Best Regards,
Damir
The error is quite clear, RestKit will not allow ambiguity so you can only have one mapping per key path.
Usually if this was for a response descriptor you would use a dynamic mapping to determine which relationship mapping was appropriate. For a request descriptor you can do something similar yourself where you analyse the object to be sent and decide which mapping is appropriate. This does mean having 2 different mappings and choosing between them manually. This could also be done using multiple RKObjectManagers, each configured with a different set of mappings.

Right way to serialize nested collection with RestKit

I'm using RestKit to POST my Album class with his nested collection o songs (Song class)
I cannot find the right way to serialize the NSArray containing album songs: it serialize the whole collection into a kind of collection of NSDictionary.
I'm using v 0.10.0 and using NSObjects not CoreData
Here is my json structure:
{"album":
{"id":12,
"source":"apple",
"collection_name":"The Platinum Collection",
"artist_name":"Queen",
"collection_id":"28007467",
"genre_id":5,
"thumb":"mythumburl.jpg",
"creation_user_id":1,
"songs":[
{"id":16,
"track_name":"Bohemian Rhapsody",
"track_time_millis":353933,
"disc_number":1,
"track_number":1,
"track_time":"00:05:53"},
...
]
}
This is my actual mapping:
RKObjectMapping *songMapping = [RKObjectMapping mappingForClass:[Song class]];
[songMapping mapKeyPath:#"id" toAttribute:#"code"];
[songMapping mapKeyPath:#"source" toAttribute:#"source"];
[songMapping mapKeyPath:#"album_id" toAttribute:#"album_id"];
[songMapping mapKeyPath:#"track_name" toAttribute:#"track_name"];
[songMapping mapKeyPath:#"track_time_millis" toAttribute:#"track_time_millis"];
[songMapping mapKeyPath:#"track_time" toAttribute:#"track_time"];
[songMapping mapKeyPath:#"disc_number" toAttribute:#"disc_number"];
[songMapping mapKeyPath:#"track_number" toAttribute:#"track_number"];
[songMapping mapKeyPath:#"preview_url" toAttribute:#"preview_url"];
[objectManager.mappingProvider setObjectMapping:songMapping forKeyPath:#"song"];
[objectManager.mappingProvider setSerializationMapping:[songMapping inverseMapping] forClass:[Song class]];
RKObjectMapping *albumMapping = [RKObjectMapping mappingForClass:[Album class]];
...
[albumMapping hasMany:#"songs" withMapping:songMapping];
// Setup our object mappings
[objectManager.mappingProvider setObjectMapping:albumMapping forKeyPath:#"album"];
[objectManager.mappingProvider setSerializationMapping:[albumMapping inverseMapping] forClass:[Album class]];

RestKit primary key attribute

I load data from a json file, I save it.
I do it twice ...
I got two entries in my Core Data sqlite database.
Even if I set in the mapping the primaryKeyAttribute.
mapping.primaryKeyAttribute = #"code";
[mapping mapAttributesFromArray :mappedFields];
[[RKObjectManager sharedManager].mappingProvider setMapping:mapping forKeyPath:entityName];
My Json
{ "MyEntity": [ { "code" : "axv2","data" : "content"}]};
Here the callback :
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
NSLog(#"Entries loaded %d",[objects count]);
lastResult = objects;
for(MyEntity * myEntity in lastResult) {
[self saveContext];
}
}
My entity is correctly mapped ... But Restkit allow one to save duplicate entries with the same primary key?
It's weird, I understood that this primary key attribute would avoid this problem.
No, that is not the case, as Core Data keeps its own keys. You can easily solve this problem by checking if your primary key exists and before saving the entity instance in question.
As of the latest RESTKit version (0.23.2) you can define the primary key like this:
[_mapping addAttributeMappingsFromDictionary:#{ #"id" : #"objectId", #"name" : #"name" }];
[_mapping setIdentificationAttributes:#[ #"objectId" ]];
Whereas objectId is you primary key on the core data object.

Resources