0

I am having serious trouble understanding how to map the user and team objects given the two REST API endpoints below. I've been reading all I could find on SO, the closest QA was this one RestKit: Creating stubs for foreign key relationships, but I am having trouble adapting it to my case.

/users

 {
      "success": 1,
      "users": [{
           "success": 1,
           "name": "Damjan",
           "surname": "Mozetič",
           "teams": [1, 2]
      }]
 }

/teams

 {
      "success": 1,
      "teams": [{
          "id": 1,
          "title": "Team name",
          "user": 1  
      }]
 }

User.swift

class User: NSManagedObject {
    @NSManaged var userId: NSNumber
    @NSManaged var firstName: String
    @NSManaged var lastName: String

    @NSManaged var teams: NSSet?

    @NSManaged var teamFKIds: NSNumber? // FK
}

Team-swift

class Team: NSManagedObject {
    @NSManaged var teamId: NSNumber
    @NSManaged var title: String

    @NSManaged var user: User?
}

Mappings:

// User
let userMapping = RKEntityMapping(forEntityForName: "User", inManagedObjectStore: mos)
userMapping.identificationAttributes = ["userId"]
userMapping.addAttributeMappingsFromDictionary([
    "id": "userId",
    "name": "firstName",
    "surname": "lastName",
    "team": "teamName",
    "teams": "teamFKIds"
])
objectManager.addResponseDescriptor(RKResponseDescriptor(mapping: userMapping, method: .GET, pathPattern: "users", keyPath: nil, statusCodes: RKStatusCodeIndexSetForClass(.Successful)))

// Team
let teamMapping = RKEntityMapping(forEntityForName: "Team", inManagedObjectStore: mos)
teamMapping.identificationAttributes = ["teamId"]
teamMapping.addAttributeMappingsFromDictionary([
    "id": "teamId",
    "title": "title"
])
objectManager.addResponseDescriptor(RKResponseDescriptor(mapping: teamMapping, method: .GET, pathPattern: "teams", keyPath: nil, statusCodes: RKStatusCodeIndexSetForClass(.Successful)))

userMapping.addConnectionForRelationship("teams", connectedBy: ["teamFKIds": "teamId"])

From what I've been reading, creating stubs for FKs is the way to go, something like this, altough I know I've messed this up a bit:

let profileStubMapping = RKEntityMapping(forEntityForName: "Profile", inManagedObjectStore: mos)
userStubMapping.addPropertyMapping(RKAttributeMapping(fromKeyPath: nil, toKeyPath: "teamFKIds"))
userStubMapping.identificationAttributes = ["userId"]
objectManager.addResponseDescriptor(RKResponseDescriptor(mapping: userStubMapping, method: .Any, pathPattern: "teams", keyPath: "userId", statusCodes: RKStatusCodeIndexSetForClass(.Successful)))

Can someone please help me understand how to properly set this up?

Also, another question. Ultimately my plan is to retrieve the whole graph into Core Data. How do I achieve this? Would simply calling getObjectsAtPath for "/users" and "/teams" do the job?

Lastly I plan on havnig the thing work offline and sync when getting online. Any tips on implementing it?

Thank you.

Community
  • 1
  • 1
Rhuantavan
  • 445
  • 3
  • 17
  • Are you always getting users first and then teams? It seems you just need stubs via a nil keypath mapping and that's it... – Wain Sep 26 '15 at 10:52
  • @Wain Yes, I do get users first. Can you show me how to setup the stubs via nil keypath? This is the part I have difficulty understanding. – Rhuantavan Sep 26 '15 at 10:55

1 Answers1

1

It looks like you want something along the lines of:

let userMapping = RKEntityMapping(forEntityForName: "User", inManagedObjectStore: mos)
userMapping.identificationAttributes = ["userId"]
userMapping.addAttributeMappingsFromDictionary([
    "id": "userId",
    "name": "firstName",
    "surname": "lastName"
])

let teamStubMapping = RKEntityMapping(forEntityForName: "Team", inManagedObjectStore: mos)
teamStubMapping.addPropertyMapping(RKAttributeMapping(fromKeyPath: nil, toKeyPath: "teamId"))
teamStubMapping.identificationAttributes = ["teamId"]

userMapping.addRelationshipMapping(sourceKeyPath: "teams", mapping: teamStubMapping)
Wain
  • 118,658
  • 15
  • 128
  • 151