Protocol¶
ObservableObject¶
An object that publishes its changes.¶
Declaration¶
protocol ObservableObject : AnyObject
Overview¶
Understanding ObservableObject¶
The ObservableObject protocol definition is as follows:
public protocol ObservableObject: AnyObject {
associatedtype ObjectWillChangePublisher: Publisher
var objectWillChange: ObjectWillChangePublisher { get }
}
This requirement is fundamental to how the SwiftUI runtime interacts with your object-based data models. It allows the runtime to react to changes in your data, and queue view updates for the UI's next render cycle.
Using ObservableObject¶
To conform to ObservableObject, simply add it to the class definition.
class AppModel: ObservableObject {
@Published var foo: Bool = false
}
To trigger objectWillChange events when your data changes, annotate your properties with the @Published property wrapper. Adding @Published to a variable causes the object to emit an objectWillChange event any time that variable is modified.
Note: This only works if you are using the default ObservableObject implementation, or if objectWillChange is an instance of ObservableObjectPublisher. If you use a custom Publisher type, you are responsible for triggering updates yourself.
Manually triggering objectWillChange¶
You can also manually trigger updates by calling ObservableObjectPublisher/send().
This is useful for cases where @Published does not suffice. For example:
class AppModel: ObservableObject {
class ChildModel {
var foo: String = "Apple"
}
var childModel = ChildModel()
func updateChildModel() {
childModel.foo = "Banana"
objectWillChange.send()
}
}
Using a custom publisher¶
In some cases, you may want to use a custom Publisher type for objectWillChange. For example:
class AppModel: ObservableObject {
public let objectWillChange = PassthroughSubject<Void, Never>()
}
- Note: The @Published property wrapper does not work with custom publishers. If you use a custom publisher, you are responsible for updating the object yourself. For example:
class AppModel: ObservableObject {
public let objectWillChange = PassthroughSubject<Void, Never>()
var foo: Bool = false {
willSet {
objectWillChange.send()
}
}
}
Using ObservableObject with SwiftUI¶
An observable object can be used to drive changes in a View, via three property wrapper types:
- @ObservedObject
- @EnvironmentObject
- @StateObject
Usage with @StateObject¶
class AppModel: ObservableObject {
@Published var foo: Bool = false
}
struct ContentView: View {
@StateObject var appModel = AppModel()
var body: some View {
Toggle("Foo", isOn: $appModel.foo)
}
}
Availability¶
iOS 13.0+
macOS 10.15+
tvOS 13.0+
watchOS 6.0+
Topics¶
Instance Property¶
objectWillChange A publisher that emits before the object has changed.
Associated Type¶
ObjectWillChangePublisher The type of publisher that emits before the object has changed.