Introduction of SwiftData
Optimize data management with SwiftData
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:
- SwiftData Compatibility
- Why You Should Choose SwiftData
- Components Driving SwiftData Operations
- CRUD Operations
- Predicate Condition
- Attribute Macro
- SwiftData VS Core Data
- 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.
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:
Components Driving SwiftData Operations
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.
The modelContainer(for:) takes an array of types:
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.
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:
2. Insert, update, and delete:
Using modelContext, you can modify the properties as shown:
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:
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:
This will retrieve data where the name is “Mansi” in the ‘employeeFilteredData’:
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:
SwiftData vs. Core Data
Demo Code
Here is the whole example of SwiftData Operations:
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.