Let's examing following code:
@propertyWrapper
struct Argument {
var wrappedValue: Int?
var argument: String
}
struct Model {
@Argument var property: Int?
@Argument(argument: "bar") var foo: Int? = nil
}
extension Model {
init(property: Int, argument: String = "hello") {
_property = Argument(wrappedValue: property, argument: argument)
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let model = Model(property: 5)
print(model)
}
}
Output looks like this:
Model(_property: propertyWrapper.Argument(wrappedValue: Optional(5), argument: "hello"), _foo: propertyWrapper.Argument(wrappedValue: nil, argument: "bar"))
So the printing function somehow has access to a property wrapper argument.
However model.property
is just Int?, the same as model.foo
. How can I extract arguments like "hello" and "bar" like this?
print(model.property.argument) // prints "hello"
print(model.foo.argument) // prints "bar"
Is this possible?
You can access foo
and property
as an Argument
inside Model
. Every property wrapped with a property wrapper declares a private property of that property wrapper's type, prefixed with an underscore. You are even assigning to the one for property
in the initialiser.
So under the hood, property
is actually declared like:
private var _property: Argument
var property: Int? {
get { _property.wrappedValue }
set { _property.wrappedValue = newValue }
}
Since it's private, you obviously can't access outside Model
, but nothing stops you from exposing it :)
// in Model
var publicProperty: Argument {
get { _property }
// not sure if a setter would be useful...
// set { _property = newValue }
}
Then you can easily print it:
print(model.publicProperty.argument)
You can even do this by modifying the property wrapper instead, by making the property wrapper be its projected value:
// in Argument
var projectedValue: Argument {
get { self }
// not sure if a setter would be useful...
// set { self = newValue }
}
// Usage: prefixing with a dollar sign gets the projected value
print(model.$property.argument)