Schema Freezing
Schema freezing is the process of creating immutable snapshots of your SwiftData schemas at specific versions. These snapshots serve as the source of truth for detecting schema drift and testing migrations.What is Schema Freezing?
When you “freeze” a schema, FreezeRay creates a permanent record of your database structure at that moment in time. This record includes:- SQLite database: A real database file with the exact schema structure
- JSON representation: Human-readable schema metadata
- SHA256 checksum: A cryptographic hash for drift detection
- Export metadata: Timestamp and version information
package-lock.json for your database schema - you know exactly what structure shipped with each version.
Why Freeze Schemas?
The Problem: SwiftData’s Hidden Dangers
SwiftData uses internal hashes to match schemas. If you modify a shippedVersionedSchema:
- Fresh installs work fine (no migration needed)
- Your simulator tests pass (fresh installs)
- Production users with existing databases crash on launch
The Solution: Frozen Fixtures
FreezeRay captures the actual database from each shipped version:- Drift detection: Checksum comparison catches accidental changes
- Migration testing: Load real v1.0.0 database and test migration to v2.0.0
- Audit trail: Git history shows exactly what shipped
How Freezing Works
1. Annotate Your Schema
Add the@FreezeSchema macro with a version string:
The
@FreezeSchema(version:) string is used by FreezeRay for fixture organization. It’s separate from SwiftData’s versionIdentifier.__freezeray_freeze_1_0_0()- Exports schema to SQLite__freezeray_check_1_0_0()- Verifies checksum matches frozen version
2. Run the Freeze Command
- CLI auto-discovers your project (no config file needed)
- Parses source files to find
@FreezeSchema(version: "1.0.0") - Builds your project
- Runs tests in iOS Simulator
- Calls the macro-generated freeze function
- Extracts SQLite files from simulator container
- Generates SHA256 checksums
- Creates scaffolded tests for drift detection
- Copies fixtures to
FreezeRay/Fixtures/1.0.0/
FreezeRay uses SwiftSyntax to automatically discover schemas. No manual configuration needed!
3. Commit to Git
Fixture Anatomy
SQLite Database (App-1_0_0.sqlite)
A real SQLite database with your schema structure:
JSON Schema (schema-1_0_0.json)
Human-readable representation:
Export Metadata (export_metadata.txt)
Freeze details:
When to Freeze
Required: Before Major Schema Changes
Freeze before releasing a new schema version to production:Optional: During Development
Freeze interim versions for testing:Not Required: Every Commit
Don’t freeze on every schema change - only when you want to seal a version as immutable.Schema Version Numbering
Schema Versions ≠ App Versions
Schema versions are independent from app versions:Common Patterns
Incremental (Simplest):Choose a versioning scheme that makes sense for your team. FreezeRay doesn’t enforce any specific format.
Best Practices
Migration Plan Structure
Keep your migration plan synchronized with frozen schemas:Type Aliases for Current Schema
Use type aliases to reference the current version throughout your app:Next Steps
Drift Detection
Learn how checksums catch accidental schema changes
Migration Testing
Test migrations between frozen versions
First Freeze Guide
Step-by-step tutorial for your first freeze
@FreezeSchema Macro
Macro reference and generated code