When I used to do Migrations, I always used ETL and then push to a dev system to review/test before going production.
The migration support is SwiftData is fine for a little tweak.
I might as well just just use new schema and context and write the custom code than use the SwiftData migration support.
SwiftData
RSS for tagSwiftData is an all-new framework for managing data within your apps. Models are described using regular Swift code, without the need for custom editors.
Posts under SwiftData tag
200 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Experiencing a crash that is only reproducible on TestFlight or AppStore version of the app, note this does not happen when running from Xcode.
I've isolated the problem to sort argument being added to @Query that fetches a model that sorts based on inherited property.
To reproduce:
@Model
class SuperModel {
var createdAt: Date = .now
}
@available(macOS 26.0, *)
@Model
class SubModel: SuperModel {
}
@Query(sort: \SubModel.createdAt, animation: .default) private var models: [SubModel]
This is probably super simple answer that I missed, but: I have an app that has a database; I'd like to create a second app (actually a CLI tool), and access the same database. Is that possible? And, if so, how? 😄
I have a SwiftData flashcard app which I am syncing with CloudKit using NSPersistentCloudKitContainer. While syncing itself is working perfectly, I have noticed a dramatic increase in the app size after enabling sync.
Specifically, without CloudKit, 15k flashcards results in the default.store file being about 4.5 MB. With CloudKit, default.store is about 67 MB. I have inspected the store and found that most of this increase is due to the ANSCKRECORDMETADATA table.
My question is, does implementing CloudKit normally cause this magnitude of increase in storage? If it doesn’t, is there something in my model, schema, implementation, etc. that could be causing it?
Below are two other posts describing a similar issue, but neither with a solution. I replied to the first one about a month ago. I then submitted this to Developer Technical Support, but was asked to post my question in the forums, so here it is.
Strange behavior with 100k+ records in NSPersistentCloudKitContainer
Huge increase in sqlite file size after adopting CloudKit
Hi everyone,
I’m running into a breaking issue with SwiftData automatic CloudKit syncing on iOS 26, and I'm trying to determine if this is a known regression or a new configuration requirement I missed.
The Setup: My setup is extremely standard; I am using the default configuration exactly as described in Apple's documentation here: https://developer.apple.com/documentation/swiftdata/syncing-model-data-across-a-persons-devices
The schema is very simple:
A single @Model class.
No relationships.
The Issue: Prior to iOS 26, this exact app was successfully syncing data between devices and to iCloud without issues. Immediately after the iOS 26 update, syncing stopped completely.
I haven't changed any code, but when I check the CloudKit Console, I am seeing some BAD_REQUEST errors during sync attempts.
Since I am using the default SwiftData sync (and not manual CKRecord handling), I’m not sure how my client code could be triggering a bad request unless the schema requirements have changed under the hood.
Questions:
Has anyone else seen increased BAD_REQUEST errors with SwiftData on iOS 26?
Are there new entitlements or strict schema requirements introduced in iOS 26 that might cause a previously valid model to be rejected by CloudKit?
Any pointers or confirmations would be appreciated. Thanks!
I am using SwiftData with CloudKit to synchronize data across multiple devices, and I have encountered an issue: occasionally, abnormal sync behavior occurs between two devices (it does not happen 100% of the time—only some users have reported this problem). It seems as if synchronization between the two devices completely stops; no matter what operations are performed on one end, the other end shows no response.
After investigating, I suspect the issue might be caused by both devices simultaneously modifying the same field, which could lead to CloudKit's logic being unable to handle such conflicts and causing the sync to stall. Are there any methods to avoid or resolve this situation?
Of course, I’m not entirely sure if this is the root cause. Has anyone encountered a similar issue?
Hi,
I was testing the new iOS 18 behavior where NSPersistentCloudKitContainer wipes the local Core Data store if the user logs out of iCloud, for privacy purposes.
I ran the tests both with a Core Data + CloudKit app, and a simple one using SwiftData with CloudKit enabled. Results were identical in either case.
In my testing, most of the time, the feature worked as expected. When I disabled iCloud for my app, the data was wiped (consistent with say the Notes app, except if you disable iCloud it warns you that it'll remove those notes). When I re-enabled iCloud, the data appeared. (all done through the Settings app)
However, in scenarios when NSPersistentCloudKitContainer cannot immediately sync -- say due to rate throttling -- and one disables iCloud in Settings, this wipes the local data store and ultimately results in data loss.
This occurs even if the changes to the managed objects are saved (to the local store) -- it's simply they aren't synced in time.
It can be a little hard to reproduce the issue, especially since when you exit to the home screen from the app, it generally triggers a sync. To avoid this, I swiped up to the screen where you can choose which apps to close, and immediately closed mine. Then, you can disable iCloud, and run the app again (with a debugger is helpful). I once saw a message with something along the lines of export failed (for my record that wasn't synced), and unfortunately it was deleted (and never synced).
Perhaps before NSPersistentCloudKitContainer wipes the local store it ought to force sync with the cloud first?
Hello,
In my iOS/SwiftUI/SwiftData app, I want the user to be able to hit [Cancel] from editing in a detail screen and return to the previous screen without changes being saved.
I believed that setting autosaveEnabled to false and/or calling .rollback would prevent changes from being saved, unless/until I call .save() when the user clicks [Save], but this does not seem to be correct.
I set modelContext.autosaveEnabled = false and I call modelContext.rollback() when the user hits [Cancel], but any changes they made are not rolled back, but saved even if I don’t call save().
I have tried setting autosaveEnabled to false when I create the ModelContainer on a @MainActor function when the App starts, and in the detail/edit screen’s .onAppear(). I can see that .rollback is being called when the [Cancel] button is tapped. In all cases, any changes the user made before hitting [Cancel] are saved.
The Developer Documentation on autosaveEnabled includes this:
“The default value is false. SwiftData automatically sets this property to true for the model container’s mainContext."
I am working on the mainContext, but it appears that setting autosaveEnabled to false has no effect no matter where in the code I set it.
If someone sees what I am doing wrong, I’d sure appreciate the input. If this description doesn’t explain the problem well enough, I’ll develop a minimal focused example.
CloudKit CKRecordZone Deletion Issue
Problem: CloudKit record zones deleted via CKDatabase.modifyRecordZones(deleting:) or CKModifyRecordZonesOperation are successfully
removed but then reappear. I suspect they are automatically reinstated by CloudKit sync, despite successful deletion confirmation.
Environment:
SwiftData with CloudKit integration
Custom CloudKit zones created for legacy zone-based sharing
Observed Behavior:
Create custom zone (e.g., "TestZone1") via CKDatabase.modifyRecordZones(saving:)
Copy records to zone for sharing purposes
Delete zone using any CloudKit deletion API - returns success, no errors
Immediate verification: Zone is gone from database.allRecordZones()
After SwiftData/CloudKit sync or app restart: Zone reappears
Reproduction:
Tested with three different deletion methods - all exhibit same behaviour:
modifyRecordZones(deleting:) async API
CKModifyRecordZonesOperation (fire-and-forget)
CKModifyRecordZonesOperation with result callbacks
Zone deletion succeeds, change tokens (used to track updates to shared records) cleaned up
But zones are restored presumably by CloudKit background sync
Expected: Deleted zones should remain deleted
Actual: Zones are reinstated, creating orphaned zones
Trying to support undo & redo in an app that utilizes Swift Data and as with anything other than provided simplistic Apple demo examples the experience is not great.
The problem:
Im trying to build functionality that allows users to add items to an item group, where item and item group have a many-to-many relationship e.g. item group can hold many items and items can appear in multiple groups.
When trying to do so with relatively simple setup of either adding or removing item group from items relationship array, I am pretty consistently met with a hard crash after performing undo & redo. Sometimes it works the first few undo & redos but 95% of the time would crash on the first one.
Could not cast value of type 'Swift.Optional<Any>' (0x20a676be0) to 'Swift.Array<App.CodableStructModel>' (0x207a2bc08).
Where CodableStructModel is a Codable Value type inside Item.
Adding and removing this relationship should be undoable & redoable as typical for Mac interaction and is "supported" by SwiftData by default, meaning that the developer has to actively either wholly opt out of undo support in their modelContainer setup or do it on a per action scale with the only thing I know of:
modelContext.processPendingChanges()
modelContext.undoManager?.disableUndoRegistration()
.....
modelContext.processPendingChanges()
modelContext.undoManager?.enableUndoRegistration()
General rant on SwiftData:
Random crashes, inconsistencies, random cryptic errors thrown by the debugger and general lack of production level stability.
Each update breaks something new and there is very little guidance and communication from the Swift Data team on how to adapt and more importantly consideration for developers that have adopted Swift Data.
If SwiftData is not ready for production, it would go a long way to clearly communicate that and mark it as Beta product.
Greetings my fellow engineers,
I use SwiftData in my iOS app. The schema is unversioned and consists of a single model. I've been modifying the model for almost two years now and relying on automatic database migrations. I had no problems for all that time, but now trying to add a property to the model or even remove a property from the model results in an error which seems like SwiftData is no longer capable of performing an automatic migration.
The log console has things like the following:
CoreData: error: NSUnderlyingError : Error Domain=NSCocoaErrorDomain Code=134190 "(null)" UserInfo={reason=Each property must have a unique renaming identifier}
CoreData: error: reason : Can't find or automatically infer mapping model for migration
CoreData: error: storeType: SQLite
CoreData: error: configuration: default
CoreData: annotation: options:
CoreData: annotation: NSMigratePersistentStoresAutomaticallyOption : 1
CoreData: annotation: NSInferMappingModelAutomaticallyOption : 1
CoreData: annotation: NSPersistentStoreRemoteChangeNotificationOptionKey : 1
CoreData: annotation: NSPersistentHistoryTrackingKey : 1
CoreData: error: <NSPersistentStoreCoordinator: 0x7547b5480>: Attempting recovery from error encountered during addPersistentStore: 0x753f8d800 Error Domain=NSCocoaErrorDomain Code=134140 "Persistent store migration failed, missing mapping model."
Have you ever encountered such an issue? What are my options?
Simple code like
struct ContentView: View {
@Query var items: [Item]
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
causes UI Hierarchy crash, on Simulators, iPhone and Mac
I found no solution but use @State with fetch descriptor.
Hi,
I am implementing a premium feature in my app where CloudKit syncing is available only for "Pro" users.
The Workflow:
Free Users: I initialize the ModelContainer with cloudKitDatabase: .none so their data stays local.
Pro Upgrade: When a user purchases a subscription, I restart the container with cloudKitDatabase: .automatic to enable syncing.
The Problem:
If a user starts as "Free" (creates local data) and later upgrades to "Pro", the app crashes immediately upon launch with the following error:
Fatal error: Failed to create ModelContainer: SwiftDataError(_error: SwiftData.SwiftDataError._Error.loadIssueModelContainer, _explanation: nil)
It seems that SwiftData fails to load the existing data once the configuration changes to expect a CloudKit-backed store.
My Question:
Is there a supported way to "toggle" CloudKit on for an existing local dataset without causing this crash? I want the user's existing local data to start syncing once they pay, but currently, it just crashes.
My code:
import Foundation
import SwiftData
public enum DataModelEnum: String {
case task, calendar
public static let container: ModelContainer = {
let isSyncEnabled = UserDefaults.isProUser
let config = ModelConfiguration(
groupContainer: .identifier("group.com.yourcompany.myApp"),
cloudKitDatabase: isSyncEnabled ? .automatic : .none
)
do {
return try ModelContainer(for: TaskModel.self, CalendarModel.self, configurations: config)
} catch {
fatalError("Failed to create ModelContainer: \(error)")
}
}()
}
Topic:
App & System Services
SubTopic:
iCloud & Data
Tags:
CloudKit
Cloud and Local Storage
SwiftData
Is there a way to view the data saved when using swiftdata? Even after deleting all models, the storage space taken up by the app in Settings is too large.
Hi
Given a simple multiplatform app about Mushrooms, stored in SwiftData, hosted in iCloud using a TextEditor
@Model
final class Champignon: Codable {
var nom: String = ""
../..
@Attribute(.externalStorage)
var attributedStringData: Data = Data()
var attributedString: AttributedString {
get {
do {
return try JSONDecoder().decode(AttributedString.self,
from: attributedStringData)
} catch {
return AttributedString("Failed to decode AttributedString: \(error)")
}
}
set {
do {
self.attributedStringData = try JSONEncoder().encode(newValue)
} catch {
print("Failed to encode AttributedString: \(error)")
}
}
}
../..
Computed attributedString is used in a TextEditor
private var textEditorView: some View {
Section {
TextEditor(text: $model.attributedString)
} header: {
HStack {
Text("TextEditor".localizedUppercase)
.foregroundStyle(.secondary)
Spacer()
}
}
}
Plain Text encode, decode and sync like a charm through iOS and macOS
Use of "FontAttributes" (Bold, Italic, …) works the same
But use of "ForegroundColorAttributes" trigger an error :
Failed to decode AttributedString: dataCorrupted(Swift.DecodingError.Context(codingPath: [_CodingKey(stringValue: "Index 3", intValue: 3), AttributeKey(stringValue: "SwiftUI.ForegroundColor", intValue: nil), CodableBoxCodingKeys(stringValue: "value", intValue: 1)], debugDescription: "Platform color is not available on this platform", underlyingError: nil))
Is there a way to encode/decode attributedString data platform conditionally ?
Or another approach ?
Thanks for advices
I have been working on an app for the past few months, and one issue that I have encountered a few times is an error where quick subsequent deletions cause issues with detached tasks that are triggered from some user actions.
Inside a Task.detached, I am building an isolated model context, querying for LineItems, then iterating over those items. The crash happens when accessing a Transaction property through a relationship.
var byTransactionId: [UUID: [LineItem]] {
return Dictionary(grouping: self) { item in
item.transaction?.id ?? UUID()
}
}
In this case, the transaction has been deleted, but the relationship existed when the fetch occurred, so the transaction value is non-nil. The crash occurs when accessing the id. This is the error.
SwiftData/BackingData.swift:1035: Fatal error: This model instance was invalidated because its backing data could no longer be found the store. PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(backing: SwiftData.PersistentIdentifier.PersistentIdentifierBacking.managedObjectID(0xb43fea2c4bc3b3f5 <x-coredata://A9EFB8E3-CB47-48B2-A7C4-6EEA25D27E2E/Transaction/p1756>)))
I see other posts about this error and am exploring some suggestions, but if anyone has any thoughts, they would be appreciated.
I'm experiencing the following error with my SwiftData container when running a build:
Code=134504 "Cannot use staged migration with an unknown model version."
Code Structure - Summary
I am using a versionedSchema to store multiple models in SwiftData. I started experiencing this issue when adding two new models in the newest Schema version. Starting from the current public version, V4.4.6, there are two migrations.
Migration Summary
The first migration is to V4.4.7. This is a lightweight migration removing one attribute from one of the models. This was tested and worked successfully.
The second migration is to V5.0.0. This is a custom migration adding two new models, and instantiating instances of the two new models based on data from instances of the existing models. In the initial testing of this version, no issues were observed.
Issue and Steps to Reproduce
Reproduction of issue: Starting from a fresh build of the publicly released V4.4.6, I run a new build that contains both Schema Versions (V4.4.7 and V5.0.0), and their associated migration stages. This builds successfully, and the container successfully migrates to V5.0.0. Checking the default.store file, all values appear to migrate and instantiate correctly.
The second step in reproduction of the issue is to simply stop running the build, and then rebuild, without any code changes. This fails to initialize the model container every time afterwards. Going back to the simulator after successive builds are stopped in Xcode, the app launches and accesses/modifies the model container as normal.
Supplementary Issue: I have been putting up with the same, persistent issue in the Xcode Preview Canvas of "Failed to Initialize Model Container" This is a 5 in 6 build issue, where builds will work at random. In the case of previews, I have cleared all data associated with all previews multiple times. The only difference being that the simulator is a 100% failure rate after the initial, successful initialization. I assume this is due to the different build structure of previews. Lastly, of note, the Xcode previews fail at the same line in instantiating the model container as the simulator does. From my research into this issue, people say that the Xcode preview is instantiating from elsewhere. I do have a separate model container set up specifically for canvas previews, but the error does not occur in that container, but rather the app's main container.
Possible Contributing Factors & Tested Facts
iOS: While I have experienced issues with SwiftData and the complier in iOS 26, I can rule that out as the issue here. This has been tested on simulators running iOS 18.6, 26.0.1, and 26.1, all encountering failures to initialize model container. While in iOS 18, subsequent builds after the successful migration did work, I did eventually encounter the same error and crash. In iOS 26.0.1 and 26.1, these errors come immediately on the second build.
Container Initialization for V4.4.6
do {
container = try ModelContainer(
for:
Job.self,
JobTask.self,
Day.self,
Charge.self,
Material.self,
Person.self,
TaskCategory.self,
Service.self,
migrationPlan: JobifyMigrationPlan.self
)
} catch {
fatalError("Failed to Initialize Model Container")
}
Versioned Schema Instance for V4.4.6 (V4.4.7 differs only by versionIdentifier)
static var versionIdentifier = Schema.Version(4, 4, 6)
static var models: [any PersistentModel.Type] {
[Job.self, JobTask.self, Day.self, Charge.self, Material.self, Person.self, TaskCategory.self, Service.self]
}
Container Initialization for V5.0.0
do {
let schema = Schema([Jobify.self,
JobTask.self,
Day.self,
Charge.self,
MaterialItem.self,
Person.self,
TaskCategory.self,
Service.self,
ServiceJob.self,
RecurerRule.self])
container = try ModelContainer(
for: schema, migrationPlan: JobifyMigrationPlan.self
)
} catch {
fatalError("Failed to Initialize Model Container")
}
Versioned Schema Instance for V5.0.0
static var versionIdentifier = Schema.Version(5, 0, 0)
static var models: [any PersistentModel.Type] {
[
JobifySchemaV500.Job.self,
JobifySchemaV500.JobTask.self,
JobifySchemaV500.Day.self,
JobifySchemaV500.Charge.self,
JobifySchemaV500.Material.self,
JobifySchemaV500.Person.self,
JobifySchemaV500.TaskCategory.self,
JobifySchemaV500.Service.self,
JobifySchemaV500.ServiceJob.self,
JobifySchemaV500.RecurerRule.self
]
}
Addressing Differences in Object Names
Type-aliasing: All my model types are type-aliased for simplification in view components. All types are aliased as 'JobifySchemeV446.<#Name#>' in V.4.4.6, and 'JobifySchemaV500.<#Name#>' in V5.0.0
Issues with iOS 26: My type-aliases dating back to iOS 17 overlapped with lower level objects in Swift, including 'Job' and 'Material'. These started to be an issue with initializing the model container when running in iOS 26. The type aliases have been renamed since, however the V4.4.6 build with the old names runs and builds perfectly fine in iOS 26
If there is any other code that may be relevant in determining where this error is occurring, I would be happy to add it. My current best theory is simply that I have mistakenly omitted code relevant to the SwiftData Migration.
I want to support Genmoji input in my SwiftUI TextField or TextEditor, but looking around, it seems there's no SwiftUI only way to do it?
If none, it's kind of disappointing that they're saying SwiftUI is the path forward, but not updating it with support for new technologies.
Going back, does this mean we can only support Genmoji through UITextField and UIViewRepresentable? or there more direct options?
Btw, I'm also using SwiftData for storage.
We have an unreleased SwiftData app for iOS18+. While we were testing I saw reports on the forum about unexpected database migrations for codable arrays on iOS26.1.
I'd like to ask a couple of questions:
1- Does this issue originate from the new Xcode version, or is it specific to iOS 26.1?
2- Is it possible to change our attribute so that users on older iOS versions receive the same model, preventing a migration from being triggered when they upgrade to iOS 26.1?
One of our models looks like this:
struct Point: Codable, Hashable {
let x: Int
let y: Int
}
@Model
class Grid {
private(set) var gridId: String = ""
var points: [Point] = []
var updatedAt: Date = Date()
private(set) var createdAt: Date = Date()
#Index<Grid>([\.gridId])
...
}
I can think of some options like:
// 1
@Attribute(.transformable(by: CustomJsonTransformer.self)) var points: [Point] = []
// 2
@Attribute(.externalStorage) var points: [Point] = []
// 3
var points: Data = Data() // store points as data
However, I'm not sure which one to use.
What would you recommend to handle this, or is there a better strategy you would suggest?
After Xcode 26.1 was updated and installing the OS 26.1 simulators, my app started crashing related to transformable properties. When I checked my schema, I noticed that properties with array collection types are suddenly set with an option transformable with Optional("NSSecureUnarchiveFromData")], even though I do not use any transformable types. I verified the macros, no transformable was specified. This is causing ModelCoders to encode/decode my properties incorrectly.
This is not an issue when I switch back to OS 26.0 simulators.