Search code examples
iosjsonswiftmappingrestkit

Mapping JSON with RestKit without attribute names


Using RestKit I am having trouble mapping the following JSON: As you see, the languages attribute/relationship does not contain any key information of the language entity.

{
  "data": {
    "version": "1.0", 
    "languages": {
      "en": "English",
      "es": "Espanol"
    }
  }
}

The json-"data" object is mapped to a RootData object, which works for the version property.

class RootData: NSManagedObject {
    @NSManaged var version: String?
    @NSManaged var languages: NSOrderedSet?
}

Now, I would like to map the keypath "data.languages" an OrderedSet of Language objects like:

class Language: NSManagedObject {
    @NSManaged var identifier: String?
    @NSManaged var name: String?
}

And I would like to end up with a collection of language objects:

(pseudo-code)
rootData.firstLanguage.identifier == "en"
rootData.firstLanguage.name == "English"

rootData.secondLanguage.identifier == "es"
rootData.secondLanguage.name == "Espanol"

But I have no idea how to map the RootData->Languages 1:n relation ship.

Thank you, any help is appreciated.


Solution

  • This Mapping solved it:

    let rootMap = RKEntityMapping(forEntityForName: "RootData", inManagedObjectStore: store)
    let rootDict = ["data.version": "version",] as [NSObject: AnyObject]!
    rootMap.addAttributeMappingsFromDictionary(rootDict)
    
    let languagesMap = RKEntityMapping(forEntityForName: "Language", inManagedObjectStore: store)
    
    
    languagesMap.forceCollectionMapping = true      // thanks @Wain
    //
    // the following solved my problem regarding the mapping:
    // - Key not present: * map from representation
    //                    * reference identifier in name-mapping
    // - Add identification attribute to keep them unique
    //
    let languageDict = ["(identifier)": "name",] as [NSObject : AnyObject]!    
    languagesMap.addAttributeMappingsFromDictionary(languageDict)
    languagesMap.identificationAttributes = ["identifier"]
    languagesMap.addAttributeMappingFromKeyOfRepresentationToAttribute("identifier")
    
    rootMap.addPropertyMapping(
        RKRelationshipMapping(
            fromKeyPath: "data.languages",
            toKeyPath: "languages", 
            withMapping: languagesMap)
        )
    

    Thanks to anyone how chimed in.