[Submitted as FB14860454, but posting here since I rarely get responses in Feedback Assistant]
In a simple SwiftData app that adds items to a list, memory usage drastically increases as items are added. After a few hundred items, the UI lags and becomes unusable.
In comparison, a similar app built with CoreData shows only a slight memory increase in the same scenario and does NOT lag, even past 1,000 items.
In the SwiftData version, as each batch is added, memory spikes the same amount…or even increases! In the CoreData version, the increase with each batch gets smaller and smaller, so the memory curve levels off.
My Question
Are there any ways to improve the performance of adding items in SwiftData, or is it just not ready for prime time?
Example Projects
Here are the test projects on GitHub if you want to check it out yourself:
PerfSwiftData
PerfCoreData
                    
                  
                iCloud & Data
RSS for tagLearn how to integrate your app with iCloud and data frameworks for effective data storage
  
    
    Selecting any option will automatically load the page
  
  
  
  
    
  
  
            Post
Replies
Boosts
Views
Activity
                    
                      Hello,
I recently switched my app from flutter which was using sqlite3 database. I would like to migrate my existing users to SwiftData.
The issue is I do not know where to start in finding the database for the current users, reading the data and inserting into the SwiftData schema.
I tried searching but not clear on how to proceed. Any help pointing in the right direction would be great. Thanks.
                    
                  
                
                    
                      I'm looking for guidance how to mitigate this crash. It seems super deep inside Core Data' FRC fetchedObjects management.
In my code, it's initiated by this
viewContext.perform {
	[unowned self] in
	self.viewContext.mergeChanges(fromContextDidSave: notification)
}
which is directly followed by the stack trace below.
Basically merging data from .NSManagedObjectContextDidSave notification from another NSManagedObjectContext. Nothing special, it works great for years, apart from these rare occurrences.
Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Reason: -[__NSCFArray objectAtIndex:]: index (235) beyond bounds (234)
Termination Reason: SIGNAL 6 Abort trap: 6
Triggered by Thread:  0
Last Exception Backtrace:
0   CoreFoundation                	0x199e947cc __exceptionPreprocess + 164 (NSException.m:249)
1   libobjc.A.dylib               	0x1971672e4 objc_exception_throw + 88 (objc-exception.mm:356)
2   CoreFoundation                	0x199fc4258 _NSArrayRaiseBoundException + 368 (NSCFArray.m:22)
3   CoreFoundation                	0x199e288a4 -[__NSCFArray objectAtIndex:] + 200 (NSCFArray.m:42)
4   CoreData                      	0x1a1e17338 -[_PFMutableProxyArray objectAtIndex:] + 40 (_PFArray.m:1860)
5   CoreData                      	0x1a1e1673c -[NSFetchedResultsController _updateFetchedObjectsWithInsertChange:] + 380 (NSFetchedResultsController.m:1582)
6   CoreData                      	0x1a1e1426c __82-[NSFetchedResultsController(PrivateMethods) _core_managedObjectContextDidChange:]_block_invoke + 2240 (NSFetchedResultsController.m:2171)
7   CoreData                      	0x1a1dcdf80 developerSubmittedBlockToNSManagedObjectContextPerform + 156 (NSManagedObjectContext.m:4002)
8   CoreData                      	0x1a1e41a44 -[NSManagedObjectContext performBlockAndWait:] + 216 (NSManagedObjectContext.m:4113)
9   CoreData                      	0x1a1e41034 -[NSFetchedResultsController _core_managedObjectContextDidChange:] + 124 (NSFetchedResultsController.m:2379)
10  CoreFoundation                	0x199e632f4 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 148 (CFNotificationCenter.c:701)
11  CoreFoundation                	0x199e63210 ___CFXRegistrationPost_block_invoke + 88 (CFNotificationCenter.c:194)
12  CoreFoundation                	0x199e63158 _CFXRegistrationPost + 436 (CFNotificationCenter.c:222)
13  CoreFoundation                	0x199e6170c _CFXNotificationPost + 728 (CFNotificationCenter.c:1248)
14  Foundation                    	0x198a84ea4 -[NSNotificationCenter postNotificationName:object:userInfo:] + 92 (NSNotification.m:531)
15  CoreData                      	0x1a1e11650 -[NSManagedObjectContext _createAndPostChangeNotification:deletions:updates:refreshes:deferrals:wasMerge:] + 1736 (NSManagedObjectContext.m:8098)
16  CoreData                      	0x1a1e10e0c -[NSManagedObjectContext _postRefreshedObjectsNotificationAndClearList] + 164 (NSManagedObjectContext.m:7631)
17  CoreData                      	0x1a1e0fad8 -[NSManagedObjectContext _processRecentChanges:] + 100 (NSManagedObjectContext.m:7714)
18  CoreData                      	0x1a1e3563c -[NSManagedObjectContext _coreMergeChangesFromDidSaveDictionary:usingObjectIDs:withClientQueryGeneration:] + 3436 (NSManagedObjectContext.m:3723)
19  CoreData                      	0x1a1e34350 __116+[NSManagedObjectContext(_NSCoreDataSPI) _mergeChangesFromRemoteContextSave:intoContexts:withClientQueryGeneration:]_block_invoke_4 + 76 (NSManagedObjectContext.m:9531)
20  CoreData                      	0x1a1dcdf80 developerSubmittedBlockToNSManagedObjectContextPerform + 156 (NSManagedObjectContext.m:4002)
21  CoreData                      	0x1a1e41a44 -[NSManagedObjectContext performBlockAndWait:] + 216 (NSManagedObjectContext.m:4113)
22  CoreData                      	0x1a1e39880 +[NSManagedObjectContext _mergeChangesFromRemoteContextSave:intoContexts:withClientQueryGeneration:] + 2372 (NSManagedObjectContext.m:9537)
23  CoreData                      	0x1a1e344a0 -[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:] + 292 (NSManagedObjectContext.m:0)
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		iCloud & Data
		
  	
                  
                
              
              
              
  
  
    
    
  
  
              
                
                
              
            
          
                    
                      Hey,
For some reason I see crashes for my iOS app related to CloudKit entitlements.
The crash happens on start up and it says:
"CKException - Application has malformed entitlements. Found value "*" for entitlement com.apple.developer.icloud-services, expected an array of strings"
I have checked my entitlements of the same build on App Store Connect and it shows "com.apple.developer.icloud-services: ( "CloudKit" )"
So I am not sure why users are having this issue. I haven't been able to reproduce it.
Does anyone have any idea why this is happening?
Thanks
                    
                  
                
                    
                      Hi everyone,
I have an application that allows to share Core Data records through CKShare.
If I compile the app in debug or release mode on my devices with Xcode the Sharing functionality work like a charm, but if I download the application from App Store doesn't work, It seems that can't generate the link for sharing.
Does anyone have any idea why?
Thanks
                    
                  
                
                    
                      Testing Environment: iOS 18.4.1 / macOS 15.4.1
I am working on an iOS project that aims to utilize the user's iCloud Drive documents directory to save a specific directory-based file structure. Essentially, the app would create a root directory where the user chooses in iCloud Drive, then it would populate user generated files in various levels of nested directories.
I have been attempting to use NSMetadataQuery with various predicates and search scopes but haven't been able to get it to directly monitor changes to files or directories that are not in the root directory.
Instead, it only monitors files or directories in the root directory, and any changes in a subdirectory are considered an update to the direct children of the root directory.
Example
iCloud Drive Documents (Not app's ubiquity container)
User Created Root Directory (Being monitored)
File A
Directory A
File B
An insertion or deletion within Directory A would only return a notification with userInfo containing data for NSMetadataQueryUpdateChangedItemsKey relating to Directory A, and not the file or directory itself that was inserted or deleted. (Query results array also only contain the direct children.)
I have tried all combinations of these search scopes and predicates with no luck:
query.searchScopes = [
  rootDirectoryURL,
  NSMetadataQueryUbiquitousDocumentsScope,
  NSMetadataQueryAccessibleUbiquitousExternalDocumentsScope,
]
NSPredicate(value: true)
NSPredicate(format: "%K LIKE '*.md'", NSMetadataItemFSNameKey)
NSPredicate(format: "%K BEGINSWITH %@", NSMetadataItemPathKey, url.path(percentEncoded: false))
I do see these warnings in the console upon starting my query:
[CRIT] UNREACHABLE: failed to get container URL for com.apple.CloudDocs
[ERROR] couldn't fetch remote operation IDs: NSError: Cocoa 257 "The file couldn’t be opened because you don’t have permission to view it."
"Error returned from daemon: Error Domain=com.apple.accounts Code=7 "(null)""
But I am not sure what to make of that, since it does act normally for finding updates in the root directory.
Hopefully this isn't a limitation of the API, as the only alternative I could think of would be to have multiple queries running for each nested directory that I needed updates for.
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		iCloud & Data
		
  	
                  
                
              
              
                Tags:
              
              
  
  
    
      
      
      
        
          
            Files and Storage
          
        
        
      
      
    
      
      
      
        
          
            iCloud Drive
          
        
        
      
      
    
      
      
      
        
          
            Foundation
          
        
        
      
      
    
  
  
              
                
                
              
            
          
                    
                      I want to clear all the data in the zone, but I can't delete it. Below is my code, no logs are printed when running.
static func clearData() {
        let coordinator = shared.container.persistentStoreCoordinator
        
        let fm = FileManager.default
        for d in shared.container.persistentStoreDescriptions {
            guard let url = d.url else { continue }
            do {
                if fm.fileExists(atPath: url.path()) {
                    try coordinator.destroyPersistentStore(at: url, type: .sqlite)
                }
            } catch {
                logger.debug("Failed to delete db file, \(error)")
            }
        }
        
        for description in shared.container.persistentStoreDescriptions {
            guard let originalStoreURL = description.url else { continue }
            let walFileURL = originalStoreURL.deletingPathExtension().appendingPathExtension("sqlite-wal")
            let shmFileURL = originalStoreURL.deletingPathExtension().appendingPathExtension("sqlite-shm")
            
            for url in [originalStoreURL, walFileURL, shmFileURL] {
                do {
                    if fm.fileExists(atPath: url.path()) {
                        try fm.removeItem(at: url)
                    }
                } catch {
                    logger.debug("Failed to delete db file, \(error)")
                }
            }
        }
        
        let container = CKContainer(identifier:  appContainerID)
        container.privateCloudDatabase.fetchAllRecordZones { zones, error in
            if let error = error {
                print("Error fetching zones: ")
            } else if let zone = zones?.first, zone.zoneID.zoneName == "_defaultZone" {
                PersistenceController.shared.container.purgeObjectsAndRecordsInZone(with: zone.zoneID, in: nil) { ckShare, error in
                    if let error = error {
                        print("Error purge zones: \(error)")
                    }
                    if ckShare == nil {
                        print("ckShare is nil")
                    }
                }
            }
        }
    }
                    
                  
                
                    
                      I am trying to save to cloud kit shared database. The shared database does not allow zones to be set up.
How do I save to sharedCloudDatabase without a zone?
private func addItem(recordType: String, name: String) {
    let record = CKRecord(recordType: recordType)
    record[Constances.field.name] = name as CKRecordValue
    record[Constances.field.done] = false as CKRecordValue
    record[Constances.field.priority] = 0 as CKRecordValue
    CKContainer.default().sharedCloudDatabase.save(record) { [weak self] returnRecord, error in
        if let error = error {
            print("Error saving record: \(record[Constances.field.name] as? String ?? "No Name"): \n \(error)")
            return
        }   
   }     
}
The following error message prints out:
Error saving record: Milk:
<CKError 0x15af87900: "Server Rejected Request" (15/2027); server message = "Default zone is not accessible in shared DB"; op = B085F7BA703D4A08; uuid = 87AEFB09-4386-4E43-81D7-971AAE8BA9E0; container ID = "iCloud.com.sfw-consulting.Family-List">
                    
                  
                
                    
                      According to my experiments SwiftData does not work with model attributes of primitive type UInt64. More precisely, it crashes in the getter of a UInt64 attribute invoked on an object fetched from the data store.
With Core Data persistent UInt64 attributes are not a problem. Does anyone know whether SwiftData will ever support UInt64?
                    
                  
                
                    
                      For a CRM application, I want users to be able to switch between accounts and have their saved contacts stored locally. Whenever a user logs in, the app should fetch data from their specific database location.
What’s the best practice to achieve this?
Should I create a separate database for each user?
Should I store all the data in one database and filter it by user?
Or is there a better approach I should consider?
                    
                  
                
                    
                      Only development environment can real sync.
But product environment can't sync.
And when run my device show this error:
CoreData: Already have a mirrored relationship registered for this key: CD_M2M_Event_items:B269B612-37A6-4ED7-9FDB-601E88BF56A8:8DC64E4A-E893-4465-8B21-48CF1C52A4BC
<NSCKMirroredRelationship: 0x302bb9950> (entity: NSCKMirroredRelationship; id: 0xa049af3fb0190928 <x-coredata://BEB6E57C-891C-4E71-B92F-7BAA0844913E/NSCKMirroredRelationship/p1747>; data: {
    cdEntityName = Event;
    ckRecordID = "B5908A8A-079E-482C-9F2E-1309BF071F0E";
    ckRecordSystemFields = nil;
    isPending = 0;
    isUploaded = 0;
    needsDelete = 0;
    recordName = "B269B612-37A6-4ED7-9FDB-601E88BF56A8";
    recordZone = "0xa049af3f6a5909a8 <x-coredata://BEB6E57C-891C-4E71-B92F-7BAA0844913E/NSCKRecordZoneMetadata/p1>";
    relatedEntityName = Item;
    relatedRecordName = "8DC64E4A-E893-4465-8B21-48CF1C52A4BC";
    relationshipName = items;
})
<decode: bad range for [%@] got [offs:941 len:665 within:0]>
And my product core data sync data only to October 24, 2024.
The data before October 24 was synchronized normally,
Nothing after October 24 is synced.
                    
                  
                
                    
                      Witam, na każdym urządzeniu Apple, iPhone’a/Watch mam możliwość instalować wersje beta developer. chciałbym wypisać się z wersji beta developer - nie mieć ich w ustawieniach. wiem że beta developer jest przypisana do mojego konta iCloud. po wylogowaniu się i przywróceniu ustawień fabrycznych, zakładka znika. gdy loguje się na konto iCloud pojawia Się wszędzie. nie zapisałem sie do developer bety. jak to usunąc?
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		iCloud & Data
		
  	
                  
                
              
              
              
  
  
    
    
  
  
              
                
                
              
            
          
                    
                      So i created an App and for some time it was working fine. The app has features to show pdf to users without logging in. I needed to upload all data to cloudkit on public database.
I was not having knowledge that there are 2 mode being a noob in coding so after i saved all records in development mode in cloudkit when i published my app, i was not able to see them (Reason because live mode works in Production mode).
So i need help now to transfer data from development mode to production mode or any app or code that can help me upload all data in production mode.
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		iCloud & Data
		
  	
                  
                
              
              
                Tags:
              
              
  
  
    
      
      
      
        
          
            CloudKit
          
        
        
      
      
    
      
      
      
        
          
            CloudKit Dashboard
          
        
        
      
      
    
      
      
      
        
          
            CloudKit Console
          
        
        
      
      
    
  
  
              
                
                
              
            
          
                    
                      I want to get to a point where I can use a small view with a query for my SwiftData model like this:
    @Query
    private var currentTrainingCycle: [TrainingCycle]
    
    init(/*currentDate: Date*/) {
        _currentTrainingCycle = Query(filter: #Predicate<TrainingCycle> {
            $0.numberOfDays > 0
//            $0.startDate < currentDate  && currentDate < $0.endDate
        }, sort: \.startDate)
    }
The commented code is where I want to go. In this instance, it'd be created as a lazy var in a viewModel to have it stable (and not constantly re-creating the view). Since it was not working, I thought I could check the same view with a query that does not require any dynamic input. In this case, the numberOfDays never changes after instantiation.
But still, each time the app tries to create this view, the app becomes unresponsive, the CPU usage goes at 196%, memory goes way high and the device heats up quickly.
Am I holding it wrong? How can I have a dynamic predicate on a View in SwiftUI with SwiftData?
                    
                  
                
                    
                      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 have two recordTypes in CloudKit: Author and Book. The Book records have their parent property set to an Author, enabling hierarchical record sharing (i.e., if an Author record is shared, the participant can see all books associated with that author in their shared database).
When syncing with CKSyncEngine, I was expecting handleFetchedRecordZoneChanges to deliver all Author records before their associated Book records. However, unless I’m missing something, the order appears to be random.
This randomness forces me to handle two codepaths in my app (opposed to just one) to replicate CloudKit references in my local persistency storage:
Book arrives before its Author → I store the Book but defer setting its parent reference until the corresponding Author arrives.
Author arrives before its Books → I can immediately set the parent reference when each Book arrives.
Is there a way to ensure that Author records always arrive before Book records when syncing with CKSyncEngine? Or is this behavior inherently unordered and I have to implement two codepaths?
                    
                  
                
                    
                      If use a SortDescriptor for a model and sort by some attribute from a relationship, in DEBUG mode it all works fine and sorts. However, in release mode, it is an instant crash.
SortDescriptor(.name, order: .reverse) ---- works
SortDescriptor(.assignedUser?.name, order: .reverse) ---- works in debug but crash in release.
What is the issue here, is it that SwiftData just incompetent to do this?
                    
                  
                
                    
                      I've developed an app that allow me to send messages to all users by entering a record in Public database. On each users device, the app takes that Public record and creates a record in their Private database to track the Read and Deleted status.
It works flawlessly on the simulator and about 1/3 of the devices enrolled in my TestFlight. The other 2/3 are unable to write to their Private database. In fact, the CKContainer.default().privateCloudDatabase.save() operation causes the app to crash if I let it run.
I've looked at every Google link and I just can't figure out why this works for 1/3 of the users, but not the other 2/3. Incidentally, the 2/3 of the group that can't save to their Private database are also unable to save their Notification Subscription.
All devices are running iOS 18.0 or better iPhone 11 through 16 in testing pool. Each portion of the working/not working group are a mix of iPhone versions.
if !found && checkIcloudStatus() {
                CKContainer.default().privateCloudDatabase.save(loadPrivateData(n: processedMessages[index].recordName)) { returnedRecord, returnedError in
                    print("Adding new message to Private and error is: \(String(describing: returnedError))")
                    DispatchQueue.main.async {
                        self.processedMessages[index].record = returnedRecord ?? CKRecord(recordType: "messages_private")
                        self.processedMessages[index].unRead = true
                        self.processedMessages[index].deleted = false
                    }
                }
            }
func loadPrivateData(n: String) -> CKRecord {
        let record = CKRecord(recordType: "messages_private")
        record["deleted"] = "false"
        record["messageId"] = n
        record["unRead"] = "true"
        return record
    }
                    
                  
                
                    
                      I'm experiencing a critical issue with SwiftData custom migrations where objects created during migration appear to be inserted successfully but aren't persisted or found by queries after migration completes. The migration logs show objects being created, but subsequent queries return zero results.
I'm migrating from schema version V2 to V2_5, which involves:
Renaming Person class to GroupData
Keeping the same data structure but changing the class name while keeping the old class.
Using a custom migration stage to copy data from old to new schema
Below is an extract of my two schema and migration plan:
Environment:
Xcode 16.0,
iOS 18.0,
Swift 6.0
SchemaV2
enum LinkMapV2: VersionedSchema {
    static let versionIdentifier: Schema.Version = .init(2, 0, 0)
    static var models: [any PersistentModel.Type] {
        [AnnotationData.self, Person.self, History.self]
    }
    
    @Model
    final class Person {
        @Attribute(.unique) var id: UUID
        var name: String
        var photo: String
        var requirement: String
        var statue: Bool
        var annotationId: UUID?
        var number: Int = 0
        
        init(id: UUID = UUID(), name: String = "", photo: String = "", requirement: String = "", status: Bool = false, annotationId: UUID? = nil, number: Int = 0) {
            self.id = id
            self.name = name
            self.photo = photo
            self.requirement = requirement
            self.statue = status
            self.annotationId = annotationId
            self.number = number
        }
    }
}
Schema V2_5
    static let versionIdentifier: Schema.Version = .init(2, 5, 0)
    static var models: [any PersistentModel.Type] {
        [AnnotationData.self, Person.self, GroupData.self, History.self]
    }
    
    // Keep the old Person model for migration
    @Model
    final class Person {
        @Attribute(.unique) var id: UUID
        var name: String
        var photo: String
        var requirement: String
        var statue: Bool
        var annotationId: UUID?
        var number: Int = 0
        
        init(id: UUID = UUID(), name: String = "", photo: String = "", requirement: String = "", status: Bool = false, annotationId: UUID? = nil, number: Int = 0) {
            self.id = id
            self.name = name
            self.photo = photo
            self.requirement = requirement
            self.statue = status
            self.annotationId = annotationId
            self.number = number
        }
    }
    
    // Add the new GroupData model that mirrors Person
    @Model
    final class GroupData {
        @Attribute(.unique) var id: UUID
        var name: String
        var photo: String
        var requirement: String
        var status: Bool
        var annotationId: UUID?
        var number: Int = 0
        
        init(id: UUID = UUID(), name: String = "", photo: String = "", requirement: String = "", status: Bool = false, annotationId: UUID? = nil, number: Int = 0) {
            self.id = id
            self.name = name
            self.photo = photo
            self.requirement = requirement
            self.status = status
            self.annotationId = annotationId
            self.number = number
        }
    }
}
Migration Plan
    static let migrationV2toV2_5 = MigrationStage.custom(
        fromVersion: LinkMapV2.self,
        toVersion: LinkMapV2_5.self,
        willMigrate: { context in
            do {
                let persons = try context.fetch(FetchDescriptor<LinkMapV2.Person>())
                
                print("=== MIGRATION STARTED ===")
                print("Found \(persons.count) Person objects to migrate")
                
                guard !persons.isEmpty else {
                    print("No Person data requires migration")
                    return
                }
                
                for person in persons {
                    print("Migrating Person: '\(person.name)' with ID: \(person.id)")
                    
                    let newGroup = LinkMapV2_5.GroupData(
                        id: person.id, // Keep the same ID
                        name: person.name,
                        photo: person.photo,
                        requirement: person.requirement,
                        status: person.statue,
                        annotationId: person.annotationId,
                        number: person.number
                    )
                    
                    context.insert(newGroup)
                    print("Inserted new GroupData: '\(newGroup.name)'")
                    
                    // Don't delete the old Person yet to avoid issues
                    // context.delete(person)
                }
                
                try context.save()
                print("=== MIGRATION COMPLETED ===")
                print("Successfully migrated \(persons.count) Person objects to GroupData")
                
            } catch {
                print("=== MIGRATION ERROR ===")
                print("Migration failed with error: \(error)")
            }
        },
        didMigrate: { context in
            do {
                // Verify migration in didMigrate phase
                let groups = try context.fetch(FetchDescriptor<LinkMapV2_5.GroupData>())
                let oldPersons = try context.fetch(FetchDescriptor<LinkMapV2_5.Person>())
                
                print("=== MIGRATION VERIFICATION ===")
                print("New GroupData count: \(groups.count)")
                print("Remaining Person count: \(oldPersons.count)")
                
                // Now delete the old Person objects
                for person in oldPersons {
                    context.delete(person)
                }
                
                if !oldPersons.isEmpty {
                    try context.save()
                    print("Cleaned up \(oldPersons.count) old Person objects")
                }
                
                // Print all migrated groups for debugging
                for group in groups {
                    print("Migrated Group: '\(group.name)', Status: \(group.status), Number: \(group.number)")
                }
                
            } catch {
                print("Migration verification error: \(error)")
            }
        }
    )
And I've attached console output below:
Console Output
                    
                  
                
                    
                      When the following models in SwiftData,
@Model
final class UndoRedoData {
    var id: [Int]
    
    init(id: [Int]) {
        self.id = id
    }
}
I created the following code.
struct ContentView: View {
    @ObservedObject var swiftDataViewModel = SwiftDataArrayViewModel.shared
    
    @State private var idArray: [Int] = [1,2,3,4]
    
    @State private var firstviewSwich: Bool = true
    @State private var twoviewSwich: Bool = false
    @State private var threeviewSwich: Bool = false
    
    var body: some View {
        VStack {
            if firstviewSwich == true {
                Button(action: addItem) {
                    Text("1.New Item")
                }
            }
            
            if twoviewSwich == true {
                Button {
                    forArrayData()
                } label: {
                     Text("2.Data Road")
                }
            }
            
            if threeviewSwich == true {
                Button(action: undoItem) {
                    Text("3.Undo")
                }
            }
        }
    }
    
    private func addItem() {
        withAnimation {
            let newItem = UndoRedoData(id: [1,2,3,4])
            swiftDataViewModel.taskContext.insert(newItem)
            
            do {
                try swiftDataViewModel.taskContext.save()
            } catch {
                print(error)
            }
            
            swiftDataViewModel.fetchItems()
            
            firstviewSwich.toggle()
            twoviewSwich.toggle()
        }
    }
    
    private func forArrayData() {
        twoviewSwich.toggle()
        for data in idArray {
            swiftDataViewModel.idUndoCreate(id: data, undoManager: swiftDataViewModel.arrayItemUndoManager)
        }
        threeviewSwich.toggle()
    }
    
    private func undoItem() {
        swiftDataViewModel.arrayItemUndoManager.undo()
        
        threeviewSwich.toggle()
        firstviewSwich.toggle()
    }
}
class SwiftDataArrayViewModel: ObservableObject {
    static let shared = SwiftDataArrayViewModel()
    
    let modelContainer: ModelContainer
       
    @ObservationIgnored
    lazy var taskContext: ModelContext = {
        return ModelContext(modelContainer)
    }()
    
    @Published var arrayItems = [UndoRedoData]()
    
    @Published var arrayItemUndoManager = UndoManager()
    
    init() {
        let schema = Schema([UndoRedoData.self])
        let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
        
        do {
            modelContainer = try ModelContainer(for: schema, configurations: [modelConfiguration])
        } catch {
            fatalError(error)
        }
        
        fetchItems()
    }
    
    func fetchItems() {
        let fetchDescriptor = FetchDescriptor<UndoRedoData>()
        do {
            arrayItems = try taskContext.fetch(fetchDescriptor)
        } catch {
            fatalError(error)
        }
    }
    
    func idUndoCreate(id: Int, undoManager: UndoManager?) {
        undoManager?.registerUndo(withTarget: self) { target in
            target.removeID()
        }
    }
    
    func removeID() {
        if let firstUndoRedoData = arrayItems.first {
            print("Before Delete:\(firstUndoRedoData.id)")
            if !firstUndoRedoData.id.isEmpty {
                firstUndoRedoData.id.removeLast()
            }
            print("After  Delete:\(firstUndoRedoData.id)")
        }
        
        do {
            try taskContext.save()
            
        } catch {
            print(error)
        }
        
        fetchItems()
    }
}
In this code, 1. Create an Item in New Item, 2. Execute Data Road and register the data in the array that is the same value as the data created in New Item in SwiftData one by one in UndoManager by for data in idArray.
This is done because the data in the array and the data created by New Item in SwiftData can be known in advance.
private func forArrayData() {
        twoviewSwich.toggle()
        for data in idArray {
            swiftDataViewModel.idUndoCreate(id: data, undoManager: swiftDataViewModel.arrayItemUndoManager)
        }
// class SwiftDataArrayViewModel: ObservableObject
func idUndoCreate(id: Int, undoManager: UndoManager?) {
        undoManager?.registerUndo(withTarget: self) { target in
            target.removeID()
        }
}
After registering in UndoManager, when Undo is executed with 3. Undo, instead of being able to perform Undo where one id is deleted each time, all the data of the id in SwiftData is deleted in a one-time Undo.
I would like to be able to delete one id each time Undo is performed and restore them in sequence, but I can only delete them all once. Does this mean that such registration to UndoManager should not be done with for statements, etc.? Or is there another problem in the code?
I want to make sure that one id is deleted for each Undo executed.