Following the Foo2
class example, I used to have my object as an ObservableObject
, I could set a @Published
value and listen to their changes the way I would do it with Combine.
Now that I am using the @Observable
macro, shown on the Foo1
example, I can not create a Combine like pipeline.
Is there a way to listen to the @Observable
macro values the way I used when using the @Published
ones from an ObservableObject
object?
@Observable class Foo1 {
var isEnabled = false
init() {
isEnabled
.map { $0 } // Error: Value of type 'Bool' has no member 'map'
}
}
class Foo2: ObservableObject {
@Published var isEnabled = false
var cancellables = Set<AnyCancellable>()
init() {
$isEnabled
.map { $0 } // Works like a charm
.sink { print($0.description) }
.store(in: &cancellables)
}
}
This seems to be a limitation, and Apple doesn't seem to mention this pattern anywhere, most likely because in most of the cases you should react to these values in views using onChange()
.
To work around this limitation, you can create a similar publisher as the one created by @Published
using CurrentValueSubject:
import Combine
@Observable class Foo1 {
var isEnabled = false {
didSet { isEnabled$.send(isEnabled) }
}
var isEnabled$ = CurrentValueSubject<Bool, Never>(false)
var cancellables = Set<AnyCancellable>()
init() {
isEnabled$
.map { $0 }
.sink { print($0.description) }
.store(in: &cancellables)
}
}