diff --git a/stdlib/public/Observation/Sources/Observation/Observable.swift b/stdlib/public/Observation/Sources/Observation/Observable.swift index cc7d1f5732c3b..fcd7fe4cff1d6 100644 --- a/stdlib/public/Observation/Sources/Observation/Observable.swift +++ b/stdlib/public/Observation/Sources/Observation/Observable.swift @@ -10,11 +10,35 @@ //===----------------------------------------------------------------------===// +/// A type that emits notifications to observers when underlying data changes. +/// +/// Conforming to this protocol signals to other APIs that the type supports +/// observation. However, applying the `Observable` protocol by itself to a +/// type doesn't add observation functionality to the type. Instead, always use +/// the ``Observation/Observable-swift.macro`` macro when adding observation +/// support to a type. @available(SwiftStdlib 5.9, *) @_marker public protocol Observable { } #if $Macros && hasAttribute(attached) +/// Defines and implements conformance of the Observable protocol. +/// +/// This macro adds observation support to a custom type and conforms the type +/// to the ``Observation/Observable-swift.protocol`` protocol. For example, the +/// following code applies the `Observable` macro to the type `Car` making it +/// observable: +/// +/// @Observable +/// class Car { +/// var name: String = "" +/// var needsRepairs: Bool = false +/// +/// init(name: String, needsRepairs: Bool = false) { +/// self.name = name +/// self.needsRepairs = needsRepairs +/// } +/// } @available(SwiftStdlib 5.9, *) #if OBSERVATION_SUPPORTS_PEER_MACROS @attached(member, names: named(_$observationRegistrar), named(access), named(withMutation)) @@ -26,6 +50,10 @@ public macro Observable() = #externalMacro(module: "ObservationMacros", type: "ObservableMacro") +/// Synthesizes a property for accessors. +/// +/// The ``Observation`` module uses this macro. Its use outside of the +/// framework isn't necessary. @available(SwiftStdlib 5.9, *) @attached(accessor, names: named(init), named(get), named(set)) #if OBSERVATION_SUPPORTS_PEER_MACROS @@ -34,6 +62,11 @@ public macro Observable() = public macro ObservationTracked() = #externalMacro(module: "ObservationMacros", type: "ObservationTrackedMacro") +/// Disables observation tracking of a property. +/// +/// By default, an object can observe any property of an observable type that +/// is accessible to the observing object. To prevent observation of an +/// accessible property, attach the `ObservationIgnored` macro to the property. @available(SwiftStdlib 5.9, *) @attached(accessor, names: named(willSet)) public macro ObservationIgnored() = diff --git a/stdlib/public/Observation/Sources/Observation/ObservationRegistrar.swift b/stdlib/public/Observation/Sources/Observation/ObservationRegistrar.swift index ccf9c63616aa1..f471b531476c7 100644 --- a/stdlib/public/Observation/Sources/Observation/ObservationRegistrar.swift +++ b/stdlib/public/Observation/Sources/Observation/ObservationRegistrar.swift @@ -9,6 +9,11 @@ // //===----------------------------------------------------------------------===// +/// Provides storage for tracking and access to data changes. +/// +/// You don't need to create an instance of `ObservationRegistrar` when using +/// the ``Observation/Observable-swift.macro`` macro to indicate observability +/// of a type. @available(SwiftStdlib 5.9, *) public struct ObservationRegistrar: Sendable { struct State: @unchecked Sendable { @@ -90,9 +95,20 @@ public struct ObservationRegistrar: Sendable { let context = Context() + /// Creates an instance of the observation registrar. + /// + /// You don't need to create an instance of + /// ``Observation/ObservationRegistrar`` when using the + /// ``Observation/Observable-swift.macro`` macro to indicate observably + /// of a type. public init() { } + /// Registers access to a specific property for observation. + /// + /// - Parameters: + /// - subject: An instance of an observable type. + /// - keyPath: The key path of an observed property. public func access( _ subject: Subject, keyPath: KeyPath @@ -106,6 +122,11 @@ public struct ObservationRegistrar: Sendable { } } + /// A property observation called before setting the value of the subject. + /// + /// - Parameters: + /// - subject: An instance of an observable type. + /// - keyPath: The key path of an observed property. public func willSet( _ subject: Subject, keyPath: KeyPath @@ -113,6 +134,11 @@ public struct ObservationRegistrar: Sendable { context.willSet(subject, keyPath: keyPath) } + /// A property observation called after setting the value of the subject. + /// + /// - Parameters: + /// - subject: An instance of an observable type. + /// - keyPath: The key path of an observed property. public func didSet( _ subject: Subject, keyPath: KeyPath @@ -120,6 +146,13 @@ public struct ObservationRegistrar: Sendable { } + /// Identifies mutations to the transactions registered for observers. + /// + /// This method calls ``willset(_:keypath:)`` before the mutation. Then it + /// calls ``didset(_:keypath:)`` after the mutation. + /// - Parameters: + /// - of: An instance of an observable type. + /// - keyPath: The key path of an observed property. public func withMutation( of subject: Subject, keyPath: KeyPath, diff --git a/stdlib/public/Observation/Sources/Observation/ObservationTracking.swift b/stdlib/public/Observation/Sources/Observation/ObservationTracking.swift index d97d69186842d..c6558fb3e38a4 100644 --- a/stdlib/public/Observation/Sources/Observation/ObservationTracking.swift +++ b/stdlib/public/Observation/Sources/Observation/ObservationTracking.swift @@ -80,6 +80,30 @@ public struct ObservationTracking { } } +/// Tracks access to properties. +/// +/// This method tracks access to any property within the `apply` closure, and +/// informs the caller of value changes made to participating properties by way +/// of the `onChange` closure. For example, the following code tracks changes +/// to the name of cars, but it doesn't track changes to any other property of +/// `Car`: +/// +/// func render() { +/// withObservationTracking { +/// for car in cars { +/// print(car.name) +/// } +/// } onChange: { +/// print("Schedule renderer.") +/// } +/// } +/// +/// - Parameters: +/// - apply: A closure that contains properties to track. +/// - onChange: The closure invoked when the value of a property changes. +/// +/// - Returns: The value that the `apply` closure returns if it has a return +/// value; otherwise, there is no return value. @available(SwiftStdlib 5.9, *) public func withObservationTracking( _ apply: () -> T,