Question

I currently have a number of entities in a Core Data database with a Web API back-end serving JSON. Each entity has a separate endpoint on the server which returns all of those entities in the database, e.g.

.../api/student
.../api/teacher
.../api/degree
etc

The JSON is serialised to include foreign key ids. Below is an example response for a student:

[
  {
    "studentID" : 1,
    "degree" : {
      "degreeID" : 1
    },
    "name" : "My Name",
    "teachers" : [
      { "teacherID" : 1 },
      { "teacherID" : 2 }
    ]
  }
]

The 'student, teacher, degree' design is a fictitious example and unfortunately the real database is more complex with lots of both 'one-to-many' and 'many-to-many' relationships.

I'm new to RestKit and not sure on the best way to request and process this data for Core Data. When the app launches, I simply need the app to update its Core Data database to match the Web API version. Any guidance on how best to request each endpoint and process the mappings would be much appreciated. Would I need to have already requested and stored the degrees and teachers before I could import the JSON above, for example? I have full control over both the client and the server.

Edit: Added example code

Below is some example code similar to mine. I have tried a number of different approaches (addRelationshipMappingWithSourceKeyPath and addConnectionForRelationship for example) to handle the 'to-many' relationship from students to teachers however I always seem to receive the following error:

relationship 'teachers' fault on managed object

Example code:

RKEntityMapping *studentMapping = [RKEntityMapping mappingForEntityForName:@"Student" inManagedObjectStore:managedObjectStore];

studentMapping.identificationAttributes = @[ @"id" ];

[studentMapping addAttributeMappingsFromDictionary:@{@"name" : @"name"}];

RKEntityMapping *teacherMapping = [RKEntityMapping mappingForEntityForName:@"Teacher" inManagedObjectStore:managedObjectStore];

tagMapping.identificationAttributes = @[ @"id" ];

[teacherMapping addAttributeMappingsFromDictionary:@{@"name" : @"name"}];

/*** RELATIONSHIP CONNECTION ***/

[studentMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"teachers" toKeyPath:@"id" withMapping:teacherMapping]];

/*** RESPONSE DESCRIPTORS ***/

RKResponseDescriptor *studentResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:studentMapping method:RKRequestMethodGET pathPattern:@"/api/student" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];

[objectManager addResponseDescriptor:studentResponseDescriptor];

RKResponseDescriptor *teacherResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:teacherMapping method:RKRequestMethodGET pathPattern:@"/api/teacher" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];

[objectManager addResponseDescriptor:teacherResponseDescriptor];
Was it helpful?

Solution

Relationships will be made to existing objects when each response is processed. Objects that don't exist are ignored by default.

You can have multiple response descriptors to create stub objects so that relationships are created and then fill the objects details in later.

Generally, I would have a single request to get the structure / relationships for 'everything' with very minimal details and then fill in the details later as the user requests it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top