Releases: fatbobman/ObservableDefaults
1.8.6
This release improves macro maintainability and fixes several behavior inconsistencies in generated code.
Fixes
- Fixed @CloudBacked diagnostics to report the correct macro type and reject invalid custom-key expressions.
- Fixed @ObservableCloud(observeFirst: true) so observable-only properties no longer participate in external cloud notification handling.
- Fixed generated @ObservableCloud(syncImmediately: true) initializers so the macro default is preserved.
- Fixed observer lifetime issues by removing host-observer retain cycles and explicitly managing notification tokens.
- Tightened macro argument validation for invalid boolean, prefix, suite-name, and interpolated string arguments.
Maintenance
- Added dedicated macro expansion snapshot, structure, and diagnostic tests.
- Added runtime regression tests for observer deallocation and post-release notification behavior.
- Documented the macro maintenance workflow and retained the new guardrail test suite for future changes.
1.8.5
Maintenance release focused on toolchain cleanup and formatting consistency.
What changed
- Removed legacy
.swiftformatand.swiftlint.ymlfiles. - Standardized the repository on Apple
swift-formatas the only formatting tool. - Updated
AGENTS.mdto document the single-tool formatting policy. - Removed obsolete inline
swiftformatandswiftlintcontrol comments from macro sources.
Validation
- Ran full test suite with
swift test. - Result: 82 tests passed across 10 suites, with 2 existing skipped cloud optional Codable tests remaining skipped.
This release does not change ObservableDefaults public API or storage behavior.
1.8.4
Maintenance release focused on repository tooling and contributor guidance.
What changed
- Added Apple swift-format configuration via
.swift-format. - Added a repository
pre-commithook in.githooks/pre-committo format staged Swift files withswift-format. - Added
AGENTS.mdwith repository-specific guidance for coding agents and maintainers. - Removed the outdated
AI_REFERENCE.mddocument to avoid duplicate or stale guidance. - Applied one-time repository formatting updates to align the codebase with the new formatter workflow.
Validation
- Ran
swift-format format --in-place --recursive --configuration .swift-format Sources Tests Package.swift. - Ran full test suite with
swift test. - Result: 82 tests passed across 10 suites, with 2 existing skipped cloud optional Codable tests remaining skipped.
This release does not change the public API or storage semantics of ObservableDefaults; it standardizes formatting and repository collaboration rules.
1.8.3
1.8.3
1.8.3 is a bug-fix release focused on external change handling for @ObservableDefaults.
Thanks to @gfreezy for the original PR and for helping surface the key-removal fallback issue addressed in this release.
Fixed
- Fixed external
UserDefaultschange handling when a key is removed.
Previously, if a property had already been changed from its declaration value and the underlying key was later removed, the model could incorrectly keep the current cached value instead of falling back. - Fixed
observeFirst: trueexternal notification handling so that@ObservableOnlyproperties are excluded from the generatedUserDefaultsnotification switch.
Only properties actually backed byUserDefaultsshould participate in external storage updates.
Fallback Behavior
This release clarifies and preserves the intended fallback order for @ObservableDefaults:
- Persisted value in the selected
UserDefaultsdomain - Value provided by
UserDefaults.register(defaults:) - Declaration-time model default captured by ObservableDefaults
That means removeObject(forKey:) does not always revert directly to the declaration default.
If a registered default exists for the key, the registered default is used first.
For @ObservableCloud, the fallback order remains:
- Persisted cloud value
- Declaration-time model default
Tests
Added and expanded coverage for:
- Removing a
UserDefaultskey and reverting to the declaration-time model default - Removing an optional key and reverting to
nil - Registered defaults taking precedence over model defaults after key removal
- The same fallback behavior on
MainActor
Also fixed cloud test isolation so .testMode tests no longer share the same mock storage domain across parallel suites.
This stabilizes full test runs and prevents unrelated cloud tests from clearing each other's state.
Documentation
- Updated
README.md - Updated
README_zh.md
Both now document the exact fallback order for UserDefaults and distinguish it from NSUbiquitousKeyValueStore.
Validation
swift testpassed before release- Full suite result: 82 tests passed, 2 existing cloud optional Codable tests remained skipped
Full Changelog: 1.8.2...1.8.3
1.8.2
What's Changed
- Fix external change handler to notify only on actual value changes.
- Add comprehensive equality tests for external UserDefaults changes, including @mainactor scenarios.
Thanks
Special thanks to original author @gfreezy (Alex.F) for the core fix in this release.
1.8.1
What's Changed
- Fix overload ambiguity for hybrid types that satisfy RawRepresentable + PropertyList (+ Codable).
- Keep storage behavior consistent: hybrid types prefer rawValue for persistence.
- Add compatibility fallback when reading hybrid types: try rawValue first, then direct PropertyList cast.
- Add and expand tests for issue #26 and combination coverage.
- Document storage resolution rules, persisted format, and fallback behavior in README (EN/中文).
Notes
- For direct key access outside macros, follow the documented storage format rules to keep behavior consistent.
1.8.0
Full Changelog: 1.7.2...1.8.0
Release 1.7.2
Fix RawRepresentable & Codable conflict (issue #23) - Add @_disfavoredOverload to resolve compilation ambiguity when types conform to both RawRepresentable and Codable - Prioritize RawRepresentable storage method for backward compatibility - Add comprehensive tests for UserDefaults and Cloud storage - Update documentation to clarify behavior Full changelog: https://github.com/fatbobman/ObservableDefaults/compare/1.7.1...1.7.2
1.7.1: Add cross-process notification support for App Groups
- Add limitToInstance parameter to @ObservableDefaults macro (default: true) - Enable system-wide UserDefaults notification listening when set to false - Essential for App Group scenarios where widgets/extensions modify shared UserDefaults - Maintain backward compatibility with default behavior unchanged Key improvements: - Support cross-process synchronization between main app and extensions - Fix issue where @Default macro cannot trigger view refresh with App Groups enabled - Add comprehensive documentation for App Group usage - Include tests for cross-process notification behavior Note: When using limitToInstance: false, always use a unique prefix to filter notifications from the intended suiteName and avoid conflicts with other UserDefaults instances.
1.7.0
- Switch legacy property-list protocols to Codable typealiases for compatibility
- Document RawRepresentable enums and add tests for raw-value storage
- Add compatibility coverage and keep optional Codable support working
Huge thanks to @NinjaLikesCheez for the original PR and discussion