Is there a way to encode and decode a property wrapper variable?

Is there a way to encode and decode a property wrapper?

say,

@propertyWrapper 
struct TestStruct {
 var value: Int = 0
 var wrappedValue: Int {
    get { return value }
    set { value = newValue }
 }
}

then

class UseTestStruct {
    @TestStruct
    var number: Int

    init(with number: int) {
        self.number = number
    }
}

now if we add an extension to this like so

extension UseTestStruct: Codable {}

the compiler starts to complain, how can we make a class with a property wrapper Codable?

For this to work, the property wrapper itself must be Codable. In a trivial wrapper like the one you show, you probably just want to pass the coding methods on to the payload, but in more complex cases you might want to add wrapper-specific behaviour.

@propertyWrapper
struct TestStruct<T> {
    var wrappedValue: T
}

extension TestStruct: Decodable where T: Decodable {
    init(from decoder: Decoder) throws {
        let value = try T(from: decoder)
        self.init(wrappedValue: value)
    }
}

extension TestStruct: Encodable where T: Encodable {
    func encode(to encoder: Encoder) throws {
        try wrappedValue.encode(to: encoder)
    }
}
1 Like

Thanks @jayton,
but will that take care of the fact that the object to be serialised is the UseTestStruct not TestStruct.

and if there is an internal value that is used via the projectedValue, then even that would need to be encoded and decoded, right?

The example is trivial to get past the basic hurdle first. The idea being that swift has made it all so magic and easy, so there should be a way to add that automagically too. Maybe there isn't.

thanks,

J

In general, property wrappers exist to introduce additional semantics to a property. The compiler can’t guess what your intended semantics are, so you have to be specific.

(With the example I gave, you can just declare class UseTestStruct: Codable and regular code generation will kick in.)

1 Like

thanks @jayton,
I guess it will be a couple of more experimentation with that as it keeps complaining that Implimentation of Decodable for non-final class cannot be automatically synthesized in extension because of initializer requirement init(from:) can only be satisfied by a required initializer in the calss definition.

Thanks for helping, but I guess it will be a bit of struggle to get that working

cheers,

J