5

I'm trying to make a generic NSCoding implementation and have a problem with decoding when the type of the object has changed in the mean time because of a newer version of the app.

I have a problem with calling the validateValue method from Swift. The function signature is:

func validateValue(_ ioValue: AutoreleasingUnsafeMutablePointer<AnyObject?>, forKey key: String, error outError: NSErrorPointer) -> Bool

As a reference, the Apple documentation can be found here: NSCoding validateValue

The code that I want to create is:

public class func decodeObjectWithCoder(theObject:NSObject, aDecoder: NSCoder) {
        for (key, value) in toDictionary(theObject) {
            if aDecoder.containsValueForKey(key) {
                let newValue: AnyObject? = aDecoder.decodeObjectForKey(key)
                NSLog("set key \(key) with value \(newValue)")
                var error:NSError?

                var y:Bool = theObject.validateValue(newValue, forKey: key, error: &error)
                if y {
                    theObject.setValue(newValue, forKey: key)
                }
            }
        }
    }

I can't get the call to .validateValue correct. I keep getting compile errors. How should I call it. The toDictionary function can be found at: EVReflection

Update: I just found out that this code does compile:

        var ioValue: AutoreleasingUnsafeMutablePointer<AnyObject?> = nil
        var y:Bool = theObject.validateValue(ioValue, forKey: key, error: nil)

This would mean that the value which is of type AnyObject? could not be casted to AutoreleasingUnsafeMutablePointer

Edwin Vermeer
  • 13,017
  • 2
  • 34
  • 58

1 Answers1

1

The newValue field had to be passed on as a pointer by adding the & in front of it. Besides that you have to use var instead of let. So the final code will be:

public class func decodeObjectWithCoder(theObject:NSObject, aDecoder: NSCoder) {
    for (key, value) in toDictionary(theObject) {
        if aDecoder.containsValueForKey(key) {
            var newValue: AnyObject? = aDecoder.decodeObjectForKey(key)
            if theObject.validateValue(&newValue, forKey: key, error: nil) {
                theObject.setValue(newValue, forKey: key)
            }
        }
    }
}
Edwin Vermeer
  • 13,017
  • 2
  • 34
  • 58