I wish to apply a custom property wrapper to a variable already wrapped in @Published
, nesting them like
(A) @Custom @Published var myVar
or
(B) @Published @Custom var myVar
(notice the application order of the wrappers).
In the case of (A) I get the error
'wrappedValue' is unavailable: @Published is only available on properties of classes
and for (B)
error: key path value type 'Int' cannot be converted to contextual type 'Updating<Int>'
neither of which are particularly helpful. Any ideas how to make it work?
import Combine
class A {
@Updating @Published var b: Int
init(b: Int) {
self.b = b
}
}
@propertyWrapper struct Updating<T> {
var wrappedValue: T {
didSet {
print("Update: \(wrappedValue)")
}
}
}
let a = A(b: 1)
let cancellable = a.$b.sink {
print("Published: \($0)")
}
a.b = 2
// Expected output:
// ==> Published: 1
// ==> Published: 2
// ==> Update: 2
The only solution I've found is a workaround: Make a custom @propertyWrapper
that has a @Published
property inside of it.
Example:
/// Workaround @Published not playing nice with other property wrappers.
/// Use this to replace @Published to temporarily help debug a property being accessed off the main thread.
@propertyWrapper
public class MainThreadPublished<Value> {
@Published
private var value: Value
public var projectedValue: Published<Value>.Publisher {
get {
assert(Thread.isMainThread, "Accessing @MainThread property on wrong thread: \(Thread.current)")
return $value
}
@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, *)
set {
assert(Thread.isMainThread, "Accessing @MainThread property on wrong thread: \(Thread.current)")
$value = newValue
}
}
public var wrappedValue: Value {
get {
assert(Thread.isMainThread, "Accessing @MainThread property on wrong thread: \(Thread.current)")
return value
}
set {
assert(Thread.isMainThread, "Accessing @MainThread property on wrong thread: \(Thread.current)")
value = newValue
}
}
public init(wrappedValue value: Value) {
self.value = value
}
public init(initialValue value: Value) {
self.value = value
}
}
Further reading:
EDIT:
I also just found this article that may provide an alternate approach, but I don't have time to investigate:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With