1

I'm trying to implement custom value transformers in a RestKit project I'm working on.

I set up my custom first value transformer as follows (Swift):

    // Join address components into a single string
    let addressValueTransformer = RKBlockValueTransformer(validationBlock: { (sourceClass, destinationClass) -> Bool in
        return sourceClass.isSubclassOfClass(NSArray.self) && destinationClass.isSubclassOfClass(NSString.self)
        }) { (inputValue, var outputValue, outputValueClass, error) -> Bool in

            let address = inputValue as NSArray
            let formattedAddress = address.componentsJoinedByString(", ")
            outputValue.memory = formattedAddress

            return true
    }

If I then add this to the defaultValueTransformer(), it doesn't work. Even the validationBlock is never called, which is a mystery. The validation block doesn't get called whether I add it to the end of the array of transformers, or at the beginning.

However, if I manually specify the valueTransformer property on the RKAttributeMapping, I can at least get it to work:

    let addressMapping = RKAttributeMapping(fromKeyPath: "location.formattedAddress", toKeyPath: "address")
    addressMapping.valueTransformer = addressValueTransformer
    placeMapping.addPropertyMapping(addressMapping)

However, I now want to add a second value transformer, this time on a one-to-one relationship with another object, and it's turning out to be an absolute nightmare...

For some reason, setting the valueTransformer on an RKRelationshipMapping (as opposed to RKAttributeMapping above), has no effect. And as I already mentioned, installing it as a generic value transformer seems to have no effect either, which is evidenced by the fact the validationBlock is never even called.

Perhaps I'm missing something critical about how value transformers work, but I wrote the following to test if I can get any value transformer's validationBlock to be called:

    let testValueTransformer = RKBlockValueTransformer(validationBlock: { (sourceClass, destinationClass) -> Bool in
        println("*** validationBlock ***")
        return true
        }) { (inputValue, var outputValue, outputValueClass, error) -> Bool in
            println("*** transform ***")
            return true
    }

    RKValueTransformer.defaultValueTransformer().insertValueTransformer(testValueTransformer, atIndex: 0)
    RKValueTransformer.defaultValueTransformer().addValueTransformer(testValueTransformer)

Based on my understanding, this should definitely be called for every value transformation, yet the validationBlock is not called once.

What's going wrong here? Is it something to do with my use of Swift (I already had to ensure my objects explicitly subclass NSObject...)?

Why are the validationBlocks never being called for custom value transformers?

And why doesn't setting valueTransformer on RKRelationshipMapping have any effect?

The RestKit documentation is unfortunately rather lacking when it comes to advanced use of custom value transformers...

Jonathan Ellis
  • 5,221
  • 2
  • 36
  • 53
  • When are you installing your value transformer? What does trace logging say it's doing when it tries to coerce your received data to the destination object? – Wain Mar 23 '15 at 22:54
  • In my case, "validationBlock" is called. The problem could be due to the podfile configuration. See this [post](http://stackoverflow.com/questions/26880337/restkit-valuetransformer-not-being-called) – EPerrin95 Mar 27 '15 at 11:32

1 Answers1

0

I ran into this issue recently and found that it was because I added the transform after I added the mappings. Once I added it before the mappings the transform got called.