I have a simple Microphone
class which conforms to @Observable
, with public
properties that trigger redraws for some SwiftUI Views
. But I also want these property changes to trigger logic in non-View
s, e.g. to start or stop speech recognition.
@Observable public class Microphone: NSObject {
public enum State: String {
case muted
case off
case on
case starting
}
public var state: State = .off
}
Before the introduction of @Observable
in iOS 17, the Microphone
would implement ObservableObject
, and its properties would be @Published
, so non-View
s could call sink()
on them to get updates. But now there doesn't seem to be a way to do this.
I tried adding @Published
to the state
property declaration, but there are two compiler errors:
>
.../Microphone.swift Cannot convert value of type 'ReferenceWritableKeyPath<Microphone, Published<Microphone.State>>' to expected argument type 'ReferenceWritableKeyPath<Microphone, Microphone.State>'
/var/folders/zl/9mrxbhjd0kxfj1763408zfh80000gq/T/swift-generated-sources/@_swiftmacro_10CDAFMobile10MicrophoneC5state18ObservationTrackedfMp.swift:1:46 Invalid redeclaration of synthesized property '_state'
The synthesized code hints that maybe I can declare the state
property as both @Published
and @ObservationIgnored
. Now it compiles, but it's unclear whether this will still cause View
s to be refreshed. Is there a better way to handle this?