Introduction of SwiftData

Optimize data management with SwiftData

Mansi Prajapati
Simform Engineering
4 min readSep 18, 2023

--

SwiftData is a framework used for data modeling and management. It uses modern Swift language macros to deliver an impeccable API experience.

It combines Core Data’s well-established persistence technology with Swift’s contemporary concurrency capabilities.

In this article, we will explore the fundamental principles of SwiftData, such as data persistence, data model creation, and CRUD operations. We will also evaluate the effectiveness of SwiftData compared to Core Data, with a focus on Swift-based applications.

Table of Contents:

  1. SwiftData Compatibility
  2. Why You Should Choose SwiftData
  3. Components Driving SwiftData Operations
  4. CRUD Operations
  5. Predicate Condition
  6. Attribute Macro
  7. SwiftData VS Core Data
  8. Demo code

Compatibility and WWDC 2023 Announcement

During WWDC 2023, SwiftData was introduced, designed to work seamlessly with iOS 17 and later. SwiftData is built using SwiftUI and integrates smoothly with various features, including widgets and CloudKit.

Why You Should Choose SwiftData

SwiftData allows you to add persistence to your application with minimal code and no external dependencies. It also offers limited offline functionality and caching.

[Gif by Giphy]

1. Automatically persistent:

If you’re familiar with Core Data, you might have used context.save() to manually store data in Core Data after each data modification. However, there’s no need for manual saving in SwiftData because, by default, SwiftData automatically saves your context to the store.

SwiftData performs autosaving in two scenarios:

  • When the app’s lifecycle state changes, such as when the app transitions from the background to the foreground or vice versa.
  • Periodic autosaving, although the exact duration of this timer is not specified in Apple’s SwiftData documentation.

2. Disable autosave and manually save data:

You can turn off autosave by setting the ‘isAutosaveEnabled’ property to ‘false’ and manually save the context when creating the container:

[Disable autosave]
[Manually save context]

Components Driving SwiftData Operations

[image by swiftyplace SwiftData Stack]

1. Model container:

This is the central object in SwiftData used for creating and managing model contexts. You can create a model container by specifying the list of model types you want to store, or customize it as needed. The model container also handles versioning, migration, and object graph separation:

  • Versioning: It tracks different schema versions for each model type.
  • Migration: The model container can automatically migrate your data to a new version of the schema.
  • Graph Separation: Objects can be separated into different graphs within the model container.

I've included this model container within a 'do-catch' block because it helps prevent errors, especially when performing lightweight migrations (e.g., adding new properties or renaming/removing existing ones in your data model). Without this precaution, you might encounter an error like Failed to find any currently loaded container for EmployeeData.

[Model container setup]

The modelContainer(for:) takes an array of types:

[Multiple model container]

2. Model context:

Model context is used to monitor changes to your model and facilitate actions for modification. It also enables tracking updates, fetching models, saving changes, and undoing them.

[Model container declaration]

CRUD Operations

1. Create model:

@Model macro: Use this to define your model's schema. It transforms the stored properties into persistent properties.

Below, you’ll find an example of creating an Employee data model with ID and name:

[Create Model Class]

2. Insert, update, and delete:

Using modelContext, you can modify the properties as shown:

[Insert, update, and delete in SwiftData]

3. Fetch data:

Using the @query macro, you can retrieve data and specify the following:

  • Sort: Sort the data based on the provided field.
  • Order: Choose between two options for ordering — forward (alphabetical order) or reverse (reverse alphabetical order).
  • Animation: Define the animation for data retrieval.

Here’s an example demonstrating how to fetch data in forward order, sorted by employee name, and with a smooth animation:

[Fetch data]

Predicate Condition

Predicates are useful for operations such as searching or filtering collections for matching elements. In data retrieval, we can use various operators to define predicate conditions, such as:

[Predicate condition operators]

This will retrieve data where the name is “Mansi” in the ‘employeeFilteredData’:

[Predicate(comparison) with query]

Attribute Macro

Attribute Macro supports fundamental value types, such as integers, strings, and floats, and more intricate data types, like enums, structs, codable, and collections. You can also apply uniqueness constraints using this macro. In the following example, I’ve utilized the “.unique” attribute, ensuring that duplicate names won’t be inserted:

[Unique attribute]

SwiftData vs. Core Data

[Difference between SwiftData and Core Data]

Demo Code

Here is the whole example of SwiftData Operations:

[SwiftData operations example]

Output:

Note: In this example, clicking ‘fetch’ will simply print the count of matches, which you can view in the console.

References:

SwiftData | Apple Developer Documentation
Meet SwiftData — WWDC23 — Videos — Apple Developer

Conclusion

Ultimately, using SwiftData in a production environment depends on your specific needs and requirements.

If you are seeking an efficient framework for data persistence, SwiftData is an excellent option. Core Data, on the other hand, is preferable for applications requiring compatibility with older iOS versions.

Additionally, it’s advisable to make full use of SwiftUI, as SwiftData is likely to become more prominent in the future.

For more updates on the latest tools and technologies, follow the Simform Engineering blog.

Follow Us: Twitter | LinkedIn

--

--