Greetings, traveler!
Property wrapper is a cool Swift feature introduced in the 5.1 version. It helps to encapsulate some logic when dealing with properties. SwiftUI uses this feature a lot. Combine’s ObservableObject
also relied on property wrappers. The number of property wrappers was reduced when the Observation framework was introduced. @Observable
Macro turns all the properties published by default, even private ones, so there is no need to mark them with the @Published
property wrapper.
But what would happen if we utilized our custom property wrapper with Observable class properties, for example, if we used a property wrapper-based DI approach?
@Observable
final class ViewModel {
var data: [String] = []
@Injected
private var dataProvider: ProviderProtocol // ❌
func loadData() {
data = dataProvider.getData()
}
}
We will receive this error.
❌ Property wrapper cannot be applied to a computed property
This will happen because the @Observable
Macro turns the stored properties into computed ones under the cut. Since we can’t use property wrappers with computed properties, we will gain such a result.
Solution
There are two solutions. We can create a new Macro to use instead of your property wrapper. However, this may not always be suitable.
Another solution is to use Apple’s @ObservationIgnored
Macro. While it is a bit weird-looking code, it will provide us with the desired result with less effort.
@Observable
final class ViewModel {
var data: [String] = []
@ObservationIgnored
@Injected
private var dataProvider: ProviderProtocol
func loadData() {
data = dataProvider.getData()
}
}
Conclusion
The key difference between Swift property wrappers and Macros is that property wrappers are executed at runtime while Macros are evaluated at compile time. So, we can’t always count Swift Macros as the property wrapper’s alternative. While they can look similar in code, this is another tool with a different purpose. So, maybe we can expect something from Apple to make combining these tools more convenient.
If you enjoyed this article, please feel free to follow me on my social media: