Skip to main content

@FreezeSchema

The @FreezeSchema macro marks a SwiftData VersionedSchema for freezing and generates helper functions for freezing and drift detection.

Overview

@FreezeSchema is an attached macro that generates two static functions:
  • __freezeray_freeze_X_Y_Z() - Exports the schema to SQLite fixtures
  • __freezeray_check_X_Y_Z() - Validates the schema hasn’t drifted from the frozen version
These functions are called by the FreezeRay CLI and scaffolded tests.

Declaration

Parameters

version

Type: String Required: Yes The version identifier for this schema. Used to organize fixtures in FreezeRay/Fixtures/<VERSION>/. Format: Any string, but semantic versioning is recommended:
  • "1.0.0" - Full semantic version
  • "1", "2" - Simple incremental
  • "2024-01-15" - Date-based
The version string is separate from SwiftData’s versionIdentifier. Use it to organize your frozen fixtures.

Usage

Basic Example

Multiple Schema Versions

Generated Code

When you add @FreezeSchema(version: "1.0.0") to a schema, the macro generates:

Freeze Function

Purpose: Exports the schema to SQLite fixtures. Called by:
  • FreezeRay CLI during freezeray freeze 1.0.0
  • Temporary test generated by CLI
What it does:
  1. Creates a ModelContainer with the schema
  2. Generates a SQLite database in iOS Simulator
  3. Exports fixtures to /tmp/FreezeRay/Fixtures/1.0.0/
  4. CLI copies fixtures to your project

Drift Check Function

Purpose: Validates the schema matches the frozen fixtures. Called by:
  • Scaffolded drift tests
  • Your test suite (on every run)
What it does:
  1. Loads frozen fixtures from FreezeRay/Fixtures/1.0.0/
  2. Generates current schema and computes checksum
  3. Compares current checksum with frozen checksum
  4. Throws FreezeRayError.schemaDrift if they don’t match

Function Naming

The generated function names use underscores instead of dots:
The double underscore prefix (__) indicates these are internal functions not meant for direct use.

Availability

Both generated functions are marked with:
This matches SwiftData’s minimum requirements.

Requirements

Must Be Applied to Enum

Must Have Version Parameter

Must Conform to VersionedSchema

How It Works

Macro Expansion

The macro is a MemberMacro that adds members (functions) to the schema enum. Before macro expansion:
After macro expansion:

Runtime Integration

The generated functions call FreezeRayRuntime methods:
See FreezeRayRuntime Reference for details on runtime behavior.

Common Use Cases

Freezing Multiple Schemas

Annotate each schema version:
Then freeze each:

Version Naming Strategies

Semantic Versioning (Recommended):
Simple Incremental:
Date-Based:

Schema Organization

Option 1: One file per version
Option 2: All schemas in one file

Debugging Macro Expansion

To see the expanded code, use Xcode’s macro expansion tool:
  1. Right-click on @FreezeSchema
  2. Select Expand Macro
  3. View the generated code inline
Or use Swift’s -print-expanded-macro flag:

Error Messages

Invalid Version Argument

Error:

Not Applied to Enum

Error:

Best Practices

Never remove @FreezeSchema from a shipped schema. The generated drift check functions are called by tests.

1. Annotate All Schema Versions

2. Use Consistent Version Format

3. Freeze Before Shipping

Add @FreezeSchema before releasing to production:
Then run:

4. Keep Annotations After Freezing

Don’t remove annotations from old schemas - drift tests depend on the generated functions.

freeze command

CLI command that calls the freeze function

Schema Freezing

Learn how schema freezing works

Drift Detection

How drift check functions detect changes

First Freeze Guide

Tutorial for using @FreezeSchema