Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call the validateValue method

Tags:

swift

nscoding

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

like image 665
Edwin Vermeer Avatar asked Nov 09 '22 19:11

Edwin Vermeer


1 Answers

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)
            }
        }
    }
}
like image 143
Edwin Vermeer Avatar answered Dec 31 '22 21:12

Edwin Vermeer