November 18, 2022
(Updated: December 10, 2022)
When you want to add a custom @propertyWrapper
to an existing @Published
variable in your SwiftUI code, e.g. in your ViewModel, you will quickly discover that @Published
does not play well with other property wrappers.
The solution I came up with is to wrap the functionality of @Published
within the custom property wrapper:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
@propertyWrapper
struct CustomFormatted {
var wrappedValue: String {
didSet {
objectWillChange?()
// assuming the functionality of `.formatted` exists in an extension
wrappedValue = wrappedValue.formatted
}
}
var objectWillChange: (() -> Void)?
init(wrappedValue: String, objectWillChange: (() -> Void)? = nil) {
self.wrappedValue = wrappedValue.formatted
self.objectWillChange = objectWillChange
}
}
|
Then, when used in a view model it can simply pass a custom operation in:
1
2
3
4
5
6
7
8
9
10
|
final class MyViewModel: ObservableObject {
@CustomFormatted
var myVariable: String = ""
init() {
_myVariable.objectWillChange = { objectWillChange.send() }
}
}
|
It is clunky but I haven’t seen a better solution yet.