Search code examples
iosswiftcore-datarestkit

Obtaining to many records with RKEntityMapping and RKRelationshipMapping


I don't find out the right mapping and get to many records.

The entity has only two attributes nid (Integer 16) and body (String).

The json (created by a Drupal Webservice, only a part of it) is like

[{
"nid":[{"value":"4"}],
"body":[{"value":"<p>test test test<\/p>   \r\n","format":"basic_html","summary":""}]
}]

and my code

    let mapping = RKEntityMapping(forEntityForName: "Content", inManagedObjectStore: manager.managedObjectStore)
    mapping.identificationAttributes = ["nid"]

    let nidMapping = RKEntityMapping(forEntityForName: "Content", inManagedObjectStore: manager.managedObjectStore)
    nidMapping.addAttributeMappingsFromDictionary([
        "value"      : "nid"
        ])

    let bodyMapping = RKEntityMapping(forEntityForName: "Content", inManagedObjectStore: manager.managedObjectStore)
    bodyMapping.addAttributeMappingsFromDictionary([
        "value"      : "body"
        ])

    mapping.addPropertyMapping(RKRelationshipMapping(fromKeyPath: "nid", toKeyPath: "nid", withMapping: nidMapping))
    mapping.addPropertyMapping(RKRelationshipMapping(fromKeyPath: "body", toKeyPath: "body", withMapping: bodyMapping))


    let responseDescriptor = RKResponseDescriptor(
        mapping: mapping,
        method: RKRequestMethod.GET,
        pathPattern: "",
        keyPath: "",
        statusCodes: NSIndexSet(index: 200)
    )

I get 3 nsmanagedobjects instead of 1:

nid nil, body nil
nid 0, body <p>test test test</p>
nid 4, body nil

Thanks!


Solution

  • Like Wain told, I had to use a custom value transformer instead of a RKRelationshipMapping:

        let transformer = RKBlockValueTransformer(validationBlock: { (inputClass:AnyClass!,outputClass:AnyClass!) -> Bool in
    
            if inputClass.isSubclassOfClass(NSArray.self) { //__NSCFArray
                return true
            }
    
            return false
    
            }) { (inputValue:AnyObject!, outputValue, outputClass, error) -> Bool in
    
                if let arr = inputValue as? NSArray {
                    if let dic = arr[0] as? NSDictionary {
                        if(outputClass.isSubclassOfClass(NSString.self)) {
                            if let str = dic["value"] as? NSString {
                                outputValue.memory = str //outputValue is AutoreleasingUnsafeMutablePointer<AnyObject?>
                                return true
                            }
                        }
                        if(outputClass.isSubclassOfClass(NSNumber.self)) {
                            if let nr = dic["value"] as? String {
                                outputValue.memory = Int(nr)
                                return true
                            }
                        }
                    }
                }
    
                return false
        }
    
        RKValueTransformer.defaultValueTransformer().addValueTransformer(transformer)
    
        let mapping = RKEntityMapping(forEntityForName: "Content", inManagedObjectStore: manager.managedObjectStore)
        mapping.addAttributeMappingsFromDictionary([
            "nid"      : "nid",
            "body"      : "body"
            ])
    
        let responseDescriptor = RKResponseDescriptor(
            mapping: mapping,
            method: RKRequestMethod.GET,
            pathPattern: "",
            keyPath: "",
            statusCodes: NSIndexSet(index: 200)
        )