@@ -109,7 +109,7 @@ extension ObservableDefaultsMacros: MemberMacro {
109109 suiteName,
110110 prefix,
111111 ignoreExternalChanges,
112- _ ,
112+ observeFirst ,
113113 limitToInstance,
114114 defaultIsolationIsMainActor,
115115 suiteNameExpression
@@ -149,7 +149,7 @@ extension ObservableDefaultsMacros: MemberMacro {
149149 }
150150
151151 // Build mapping between properties and their UserDefaults keys
152- let metas : [ ( userDefaultsKey: String , propertyID: String ) ] = persistentProperties
152+ let metas : [ ( userDefaultsKey: String , propertyID: String , isBacked : Bool ) ] = persistentProperties
153153 . map { property in
154154 let key =
155155 property. attributes. extractValue (
@@ -159,7 +159,10 @@ extension ObservableDefaultsMacros: MemberMacro {
159159 forAttribute: DefaultsKeyMacro . name,
160160 argument: DefaultsKeyMacro . key) ?? property. identifier? . text ?? " "
161161 let propertyID = property. identifier? . text ?? " "
162- return ( key, propertyID)
162+ // In observeFirst mode, only explicitly @DefaultsBacked properties are backed;
163+ // otherwise all persistent properties are backed.
164+ let isBacked = !observeFirst || property. hasAttribute ( named: DefaultsBackedMacro . name)
165+ return ( key, propertyID, isBacked)
163166 }
164167
165168 // Generate keyPath mapping for external change handling
@@ -178,11 +181,26 @@ extension ObservableDefaultsMacros: MemberMacro {
178181 let caseCode = metas. enumerated ( ) . map { index, meta in
179182 let caseIndent = index == 0 ? " " : " "
180183 // swiftformat:disable all
181- if hasMainActor {
184+ if !meta. isBacked {
185+ // ObservableOnly properties are not stored in UserDefaults,
186+ // so we cannot compare values — keep the original behavior.
187+ if hasMainActor {
188+ return """
189+ \( caseIndent) case prefix + " \( meta. userDefaultsKey) " :
190+ \( caseIndent) MainActor.assumeIsolated {
191+ \( caseIndent) host._$observationRegistrar.withMutation(of: host, keyPath: \\ . \( meta. propertyID) ) {}
192+ \( caseIndent) }
193+ """
194+ } else {
195+ return """
196+ \( caseIndent) case prefix + " \( meta. userDefaultsKey) " : host._$observationRegistrar.withMutation(of: host, keyPath: \\ . \( meta. propertyID) ) {}
197+ """
198+ }
199+ } else if hasMainActor {
182200 return """
183201 \( caseIndent) case prefix + " \( meta. userDefaultsKey) " :
184202 \( caseIndent) MainActor.assumeIsolated {
185- \( caseIndent) let newValue = UserDefaultsWrapper.getValue(fullKey, host._ \( meta. propertyID) , host._userDefaults)
203+ \( caseIndent) let newValue = UserDefaultsWrapper.getValue(fullKey, host._default_value_of_ \( meta. propertyID) , host._userDefaults)
186204 \( caseIndent) if host.shouldSetValue(newValue, host._ \( meta. propertyID) ) {
187205 \( caseIndent) host._ \( meta. propertyID) = newValue
188206 \( caseIndent) host._$observationRegistrar.withMutation(of: host, keyPath: \\ . \( meta. propertyID) ) {}
@@ -192,7 +210,7 @@ extension ObservableDefaultsMacros: MemberMacro {
192210 } else {
193211 return """
194212 \( caseIndent) case prefix + " \( meta. userDefaultsKey) " :
195- \( caseIndent) let newValue = UserDefaultsWrapper.getValue(fullKey, host._ \( meta. propertyID) , host._userDefaults)
213+ \( caseIndent) let newValue = UserDefaultsWrapper.getValue(fullKey, host._default_value_of_ \( meta. propertyID) , host._userDefaults)
196214 \( caseIndent) if host.shouldSetValue(newValue, host._ \( meta. propertyID) ) {
197215 \( caseIndent) host._ \( meta. propertyID) = newValue
198216 \( caseIndent) host._$observationRegistrar.withMutation(of: host, keyPath: \\ . \( meta. propertyID) ) {}
0 commit comments