Core Data

RSS for tag

Save your application’s permanent data for offline use, cache temporary data, and add undo functionality to your app on a single device using Core Data.

Posts under Core Data tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

EXC_CRASH from NSManagedObjectContext executeFetchRequest
Hello, I have an iOS app for which I've received a number of similar crash reports over the last few months. Despite a lot of effort, I haven't been able to replicate the crash myself and I'm finding it difficult to diagnose. The main view of the app loads a list of items from Core Data using @FetchRequest and looking at the logs it appears to me that this is the most likely source of the crash as the call stack includes SwiftUI 0x19c78c368 FetchRequest.update() + 472 (FetchRequest.swift:406). It also appears as if this happens on launch as the crash times and launch times are always very similar. I've attempted lots of things to try and replicate the crash, such as launching the app a lot of times, creating lots of items so that the fetch request has a lot of data to retrieve, performing any other database related actions in the app immediately after launch to try and drive out any concurrency issues and simulating degraded thermal and network conditions for the device. I've included a sample crash report, I'd be very grateful if anyone has any suggestions for diagnosing the issue. Crash Report
7
0
274
3w
Recommendations/Advice on Core Data template entity approach
Prerequisites I have three entities: Record, Header, and Row. Record: id index date children (one-to-many relationship with Header entities) Header: id index title parent (Record) (Is null if this Header is a subheader) headerParent (Header) (Is null if this Header is not a subheader) subheaders (one-to-many relationship with Header entities) children (one-to-many relationship with Row entities) Row: id index title value parent (Header) Issue I need to have default data in these entities. When creating a new Record, I want it to copy all default entity data (except for the Row's value) to generate a new Record ready for new notes. Additionally, if the order (index) of the entities' data or their titles are updated, I want the default data to update automatically so the user doesn't have to make these changes manually every time. Proposed Solution My approach is to add a field called isBaseEntity to each entity. When isBaseEntity is true, this entity contains the default information. I would then update this base entity with any changes made to the non-base ones. Additionally, I would exclude this base entity when fetching the rest of the data, as it serves as the default template. Question Is this a good and efficient approach? Do you have any other suggestions or recommendations for improving this? I would really appreciate any help you can provide.
0
0
163
Jul ’24
Core Data crashes when attempting to establish relationship to an entity with derived attribute in the background
I have recently moved some of my data save operations from the view context to background contexts. Since the switch, some (but not all) of my users are reporting that the background save operations crash 100% of the time. After researching, I have narrowed it down to the fact that these save operations involve establishing a relationship to an entity with a derived attribute. An example is shown below: try await CoreDataStack.shared.performBackgroundTask { context in var transaction = Transaction(context: context) transaction.amount = NSDecimalNumber(decimal: 0) transaction.id = UUID() let account = Account.account(withName: "Default", in: context) transaction.account = account try context.save() } // <= Crashes! In the above example, each Transaction has a to-one relationship to an Account, and the latter has a to-many relationship the the former. Account has a derived attribute called balance that is calculated using the expression sum:(transactionItems.amount). The would then crash when the performBackgroundTask block exits (after the save() operation returns): Thread 4 Crashed: 0 libobjc.A.dylib 0x00000001850ae00c objc_release_x8 + 8 1 CoreData 0x00000001900d8cfc -[_CDSnapshot dealloc] + 72 (_CDSnapshot.m:691) 2 CoreData 0x00000001900d8b68 _NSQLRow_dealloc_standard + 48 (NSSQLRow.m:156) 3 CoreFoundation 0x0000000187d72228 __CFBasicHashRemoveValue + 192 (CFBasicHash.c:1332) 4 CoreFoundation 0x0000000187d7212c CFBasicHashRemoveValue + 452 (CFBasicHash.c:1418) 5 CoreFoundation 0x0000000187d71638 CFDictionaryRemoveValue + 196 (CFDictionary.c:477) 6 CoreData 0x00000001900f6fa8 -[NSPersistentStoreCache decrementRefCountForObjectID:] + 96 (NSPersistentStoreCache.m:120) 7 CoreData 0x00000001900f6eec -[NSSQLCore managedObjectContextDidUnregisterObjectsWithIDs:generation:] + 172 (NSSQLCore.m:4329) 8 CoreData 0x00000001900f30f4 0x1900d6000 + 119028 9 CoreData 0x00000001900f4d74 gutsOfBlockToNSPersistentStoreCoordinatorPerform + 204 (NSPersistentStoreCoordinator.m:404) 10 libdispatch.dylib 0x000000018fe9b0d8 _dispatch_client_callout + 20 (object.m:576) 11 libdispatch.dylib 0x000000018fea26e0 _dispatch_lane_serial_drain + 744 (queue.c:3934) 12 libdispatch.dylib 0x000000018fea31e8 _dispatch_lane_invoke + 380 (queue.c:4025) 13 libdispatch.dylib 0x000000018feae258 _dispatch_root_queue_drain_deferred_wlh + 288 (queue.c:7185) 14 libdispatch.dylib 0x000000018feadaa4 _dispatch_workloop_worker_thread + 532 (queue.c:6779) 15 libsystem_pthread.dylib 0x000000020f3c0c7c _pthread_wqthread + 288 (pthread.c:2696) 16 libsystem_pthread.dylib 0x000000020f3bd488 start_wqthread + 8 performBackgroundTask is defined as: func performBackgroundTask<T>(_ block: @escaping (NSManagedObjectContext) throws -> T) async rethrows -> T { try await container.performBackgroundTask { context in context.transactionAuthor = appTransactionAuthorName context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy return try block(context) } } Things to note: If I do not establish the relationship to Account from Transaction, the crash doesn't happen; if I uncheck derived on the balance attribute of Account, the crash also does not happen. For those users who are experiencing the crash, the crash rate is 100%; for those who aren't experiencing the crash, the crash never happens. So it's either 100% or 0%. I have double checked all concurrency usages and all operations are performed within NSPersistentCloudKitContainer's performBackgroundTaskmethod, so it's probably not a threading issue. I have also tried ASan, Core Data's concurrency debug, as well as Zombie objects to no avail. The crash seems to be related to a user's existing data. While I couldn't reproduce the crash on my own database, once I replaced the underlying SQLite file with one of my crashing user's, the crash is 100% reproducible. I am at my wit's end here. Is this an internal Core Data bug, or am I doing something incorrectly? Any help is greatly appreciated!
3
3
304
4w
Crash when accessing Core Data because file couldn't be opened
We have a crash regarding to Core Data access that was not reproducible in our side but the crash count keeps increasing with the last stack trace is assertionFailure from Apple internal SDK. The last stack trace before the assertionFailure by system is our code initializing CoreData in DataContainer.init(name:bundle:inMemory:) where we will try to access CoreData and the error message we found from our 3rd party crash reporter is something like this DataStore/DataContainer.swift:30: Fatal error: Unresolved error Error Domain=NSCocoaErrorDomain Code=256 "The file “Content.sqlite” couldn’t be opened. UserInfo={NSFilePath=/var/mobile/Containers/Data/Application/9DBF262C-851A-486B-90CC-4397A8896525/Library/Application Support/Content.sqlite, NSSQLiteErrorDomain=13}, ["NSSQLiteErrorDomain": 13, "NSFilePath": /var/mobile/Containers/Data/Application/9DBF262C-851A-486B-90CC-4397A8896525/Library/Application Support/Content.sqlite] That sqlite file is supposed to be file used by Core Data (since we have no other code that access it) and we are quite confused on why sometimes the CoreData cannot be accessed with that kind of error message. So far, we still have no idea to reproduce it and what do to resolve it. I have submitted the report with bug number: FB14433998 I attached an example of the crash report here too. Please gave us insight on why it happened and how we can prevent it from happening again. crash log 1.crash
1
0
237
2w
Core Data Crash: Could not merge changes
We have one Persistent store coordinator(PSC). On top of this we have two managed object contexts(MOC), one with private queue concurrency(bgMOC) persistentContainer.newBackgroundContext() and another with main queue concurrency(mainMOC). persistentContainer.viewContext We have verified that only one PSC is connected to the sqlite. We only have one PSC object and only one bgMOC. We always use bgMOC for writes. And main for UI just reads and UI purposes. We strictly follow access of managed objects in the contexts .perform { } always. Problem: We see lots of Merge Conflicts We have printed the conflict attributes and found object snapshot is always null cached snapshot is printed persisted snapshot is printed Our findings: Sometimes cached snapshot is same as persisted snapshot and sometimes there is a diff in some property(not sure relationships diff as snapshot dont have these info). The NSManagedObject current values match the persistent store snapshot always. In one of the logs we concluded that the cachedRow was stale, and both the managed object and persisted values were same with newer values. How do we proceed to fix this? Is cached row supposed to be synchronously updated with every save that happens? We dont want to put a merge policy as we think conflicts should not happen at first place as we are always writing via same bgMoc Additional information Our app does lots of quick(within 1-2 ms) bgMoc.perform { change, bgMoc.save } back to back and on same objets as well. Some places we have noticed if we try to dump a same change two times in quick succession via same bgMoc this crash happens. But we were not able to reproduce this on dev systems. something like bgMoc.perform { obj1.changeX, bgMoc.save } bgMoc.perform {obj1. changeX, bgMoc.save } We also do bgMocPerorm inside bgMoc.perofrm like this bgMoc.perform { on some managed objects validate a condition early exist if fails. onSomeOtherThreadComputeSomeStuff { success in bgMoc.perform { someChange bMoc.save() } } } Crash log [Debug] [NSManagedObjectContext 0x303b11e10] [NSManagedObjectContext+Enhancements.swift:32] > Save error. Error : Error Domain=NSCocoaErrorDomain Code=133020 "Could not merge changes." UserInfo={conflictList=( "NSMergeConflict (0x301aa97c0) for NSManagedObject (0x302045c70) with objectID '0x8d881a3c1b3524ba <x-coredata://412EE632-D802-451E-99DF-50ADF230B800/MailThread/p1416>' with oldVersion = 2 and newVersion = 3 and old cached row = {\n attachmentCount = 0;\n firstScheduledDate = \"<null>\";\n id = 2164154918090767;\n lastMessageDraftDate = \"<null>\";\n lastMessageReceivedDate = \"2024-07-16 18:31:34 +0000\";\n lastMessageSentDate = \"<null>\";\n messageCount = 1;\n rawFlags = 0;\n snippet = \"snippet1\";\n subject = \"subject1\";\n transactionIdAsNumber = 2164277798615057;\n umc = 1;\n} and new database row = {\n attachmentCount = 0;\n firstScheduledDate = \"<null>\";\n id = 2164154918090767;\n lastMessageDraftDate = \"<null>\";\n lastMessageReceivedDate = \"2024-07-16 18:31:34 +0000\";\n lastMessageSentDate = \"<null>\";\n messageCount = 1;\n rawFlags = 0;\n snippet = \"snippet1\";\n subject = \"subject1\";\n transactionIdAsNumber = 2164277798615057;\n umc = 1;\n}"
0
0
211
Jul ’24
SwiftData - error: Error: Persistent History (2) has to be truncated due to the following entities being removed: ( A )
I'm having trouble resolving the error. If I save data in view A and open view B, I get an error. If I open only view A, or only view B, there is no problem, but when I open a second view (A to B, B to A, etc.) I get an error. Attached is the code that reproduces the problem. We would appreciate your cooperation. No simulator is used. Xcode: Version 15.4 (15F31d) iPone11: 17.5.1 Thank you. Error error: Error: Persistent History (2) has to be truncated due to the following entities being removed: ( A ) warning: Warning: Dropping Indexes for Persistent History warning: Warning: Dropping Transactions prior to 2 for Persistent History warning: Warning: Dropping Changes prior to TransactionID 2 for Persistent History Code import SwiftUI import SwiftData @main struct issueApp: App { var body: some Scene { WindowGroup { ContentView() .modelContainer(for: [A.self, B.self]) } } } import SwiftUI import SwiftData struct ContentView: View { @State var showAView: Bool = false @State var showBView: Bool = false var body: some View { VStack { Button("show A"){ showAView.toggle() } .sheet(isPresented: $showAView){ AView() } Button("show B"){ showBView.toggle() } .sheet(isPresented: $showBView){ BView() } } } } struct AView: View { @Environment(\.modelContext) var context @Query private var list: [A] let query = QueryData<A>() var body: some View { VStack { if list.count > 0 { VStack { List { ForEach(list, id: \.number){ item in VStack { Text(item.number) } } } Button("clear"){ try? context.delete(model: A.self) } } } else { Button("set"){ query.set(data: A(number: "1")) } } } } } struct BView: View { @Environment(\.modelContext) var context @Query private var list: [B] let query = QueryData<B>() var body: some View { VStack { if list.count > 0 { VStack { List { ForEach(list, id: \.number){ item in VStack { Text(item.number) } } } Button("clear"){ try? context.delete(model: B.self) } } } else { Button("set"){ query.set(data: B(number: "1")) } } } } } class QueryData<T: PersistentModel> { private var container: ModelContainer? init() { self.container = try? ModelContainer(for: T.self) } func set(data: T) { guard let container = self.container else { return } let context = ModelContext(container) do { try context.delete(model: T.self) context.insert(data) try context.save() } catch { print("error: \(error)") } } } @Model final class A { var number: String init(number: String) { self.number = number } } @Model final class B { var number: String init(number: String) { self.number = number } }
2
0
337
Jul ’24
Public and Private CK sync failure, macOS mistake = add data before indexing
I have a Multiplatform app for iOS and macOS targets. I am using CloudKit with CoreData and have successfully established a private and public database. The app has successfully synced private and public data for months between macOS (dev machine), an iPhone 13 Pro and an iPad Pro 12.9inch 2nd gen. The public data also syncs perfectly to simulator instances running under other iCloud accounts. Recently I added a new entity in the public DB and here is where I seemed to have made a mistake. I entered data into the new public database via my developer UI built into the macOS app running on my MBP before I indexed the necessary fields. Side note - I find it necessary to index the following for each Entity to ensure iCloud sync works as expected on all devices... modifiedTimestamp - Queryable modifiedTimestamp - Sortable recordName - Queryable Realising my mistake, I indexed the above CKRecord fields for the new Entity. Since then, the macOS target has remained in some way "frozen" (for want of a better term). I can add new public or private records in the macOS app but they do not propagate to the public or private stores in iCloud. I have attempted many fixed, some summarised below: clean build folder from Xcode; remove all files from the folder /Users//Library/Containers/, place in recycle bin, empty recycle bin, then build and run; build and run on iPhone and iPad targets to ensure all apps are current dev version, then repeat above processes. I've read through the console logging when I build and run the macOS app many many times to see whether I can find any hint. The closest thing I can find is... BOOL _NSPersistentUIDeleteItemAtFileURL(NSURL *const __strong) Failed to stat item: file:///Users/<me>/Library/Containers/com.me.AppName/Data/Library/Saved%20Application%20State/com.me.AppName.savedState/restorecount.plist but my research on this and other forums suggests this is not relevant. Through this, the app still functions as expected on iOS devices and both private and public database additions and modifications propagate to iCloud stores and to other devices. I expect that removing the macOS app entirely from my dev machine would trigger a complete sync with all existing data. Imagine I bought a new macOS device and chose to install my app where before I had run this only on my iOS devices. My current problem suggests that I could not do this, but I know that this is not the intended behaviour. This scenario makes me think there is a setting file for my macOS app that I'm not aware of and that this impeding the sync of all existing app data back to the fresh install of the macOS app? But that is a wild guess. Running public releases (no betas) Xcode 15.4 (15F31d) macOS Sonoma 14.5 physical iOS devices running iOS 17.5.1 Any words of wisdom on how I might go about trying to solve this problem please?
1
0
319
Jul ’24
Regression macOS 15 beta: NSTableViewDiffableDataSource does not call the 'cellProvider' when the data of a visible cell changes
In one of my apps, I use NSTableViewDiffableDataSource in tandem with NSFetchedResultsController, which provides the necessary snapshots. This works great in macOS 14.5. However in latest macOS 15 betas, NSTableViewDiffableDataSource does not call the 'cellProvider' completion handler anymore when the data of a visible cell changes. When data of a visible cell changes, the didChangeContentWith method of NSFetchedResultsController is called correctly, but applying the provided snapshot doesn’t result in calling the said 'cellProvider' completion handler. This looks a rollback to the early state of this API in 2020. It concerns this piece of code: dataSource = NSTableViewDiffableDataSource(tableView: tableView, cellProvider: { (tableView, tableColumn, row, item) -> NSView in // Return a cell view with data }) Does anyone know a solution or workaround to get animated updates of visible cells working in macOS 15 beta? Yes, applying the snapshot without animation works, but that’s not where NSTableViewDiffableDataSource is designed for. In case an Apple engineer reads this: Looking at the sample code associated with FB13931189, is there anything wrongly implemented that prevents calling the 'cellProvider' method for visible cells? Is this perhaps actually a bug of NSFetchedResultsController? I’m asking this because NSCollectionViewDiffableDataSource does have a very similar problem (FB13943853). PS Yes, this post looks very similar to https://developer.apple.com/forums/thread/759381#759381021, because the problem is identical except that concerns NSCollectionViewDiffableDataSource.
0
1
265
Jul ’24
Regression macOS 15 beta: NSCollectionViewDiffableDataSource does not call the 'itemProvider' when the data of a visible item changes
In one of my apps, I use NSCollectionViewDiffableDataSource in tandem with NSFetchedResultsController, which provides the necessary snapshots. This works great in macOS 14.5. However, when updating data in Core Data related to a visible item in a NSCollectionView, the NSCollectionViewDiffableDataSource no longer calls the ‘itemProvider’ closure of the diffable data source when using macOS 15 Seed 3, after applying a snapshot with animation. As a result of this, the collection view does not update visible items when the related data changes. I’m talking about this piece of code which is no longer called when it concerns a visible item: dataSource = NSCollectionViewDiffableDataSource<String, NSManagedObjectID>(collectionView: collectionView, itemProvider: { // Return an NSCollectionViewItem here }) Does anyone know a workaround or solution to get updating of visible cells working in macOS 15 Seed 3, without losing animated updates? In case an Apple engineer is reading this: Are there any related API changes that must be taken into account? Is this perhaps actually a bug of NSFetchedResultsController? I’m asking this because NSTableViewDiffableDataSource does have a very similar problem in macOS 15 beta. See also FB13943853
0
0
265
Jul ’24
How to save to specific stores/configurations in Core Data
I'm currently syncing core data with the CloudKit private and public databases, as you can see in the code below, I'm saving the private database in the default configuration in Core Data and the public in a configuration called Public everything works fine when NSPersistentCloudKitContainer syncs, what I'm having an issue with is trying to save to the public data store PublicStore, for instance when I try to save with func createIconImage(imageName: String) it saves the image to the "default" store, not the PublicStore(Public configuration). What could I do to make the createIconImage() function save to the PublicStore sqlite database? class CoreDataManager: ObservableObject{ static let instance = CoreDataManager() private let queue = DispatchQueue(label: "CoreDataManagerQueue") @AppStorage(UserDefaults.Keys.iCloudSyncKey) private var iCloudSync = false lazy var context: NSManagedObjectContext = { return container.viewContext }() lazy var container: NSPersistentContainer = { return setupContainer() }() init(inMemory: Bool = false){ if inMemory { container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") } } func updateCloudKitContainer() { queue.sync { container = setupContainer() } } private func getDocumentsDirectory() -> URL { return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] } private func getStoreURL(for storeName: String) -> URL { return getDocumentsDirectory().appendingPathComponent("\(storeName).sqlite") } func setupContainer()->NSPersistentContainer{ let container = NSPersistentCloudKitContainer(name: "CoreDataContainer") let cloudKitContainerIdentifier = "iCloud.com.example.MyAppName" guard let description = container.persistentStoreDescriptions.first else{ fatalError("###\(#function): Failed to retrieve a persistent store description.") } description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) if iCloudSync{ if description.cloudKitContainerOptions == nil { let options = NSPersistentCloudKitContainerOptions(containerIdentifier: cloudKitContainerIdentifier) description.cloudKitContainerOptions = options } }else{ print("Turning iCloud Sync OFF... ") description.cloudKitContainerOptions = nil } // Setup public database let publicDescription = NSPersistentStoreDescription(url: getStoreURL(for: "PublicStore")) publicDescription.configuration = "Public" // this is the configuration name if publicDescription.cloudKitContainerOptions == nil { let publicOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: cloudKitContainerIdentifier) publicOptions.databaseScope = .public publicDescription.cloudKitContainerOptions = publicOptions } container.persistentStoreDescriptions.append(publicDescription) container.loadPersistentStores { (description, error) in if let error = error{ print("Error loading Core Data. \(error)") } } container.viewContext.automaticallyMergesChangesFromParent = true container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy return container } func save(){ do{ try context.save() //print("Saved successfully!") }catch let error{ print("Error saving Core Data. \(error.localizedDescription)") } } } class PublicViewModel: ObservableObject { let manager: CoreDataManager @Published var publicIcons: [PublicServiceIconImage] = [] init(coreDataManager: CoreDataManager = .instance) { self.manager = coreDataManager } func createIconImage(imageName: String) { let newImage = PublicServiceIconImage(context: manager.context) newImage.imageName = imageName newImage.id = UUID() save() } func save() { self.manager.save() } }
1
0
310
Jul ’24
How does NSFetchRequest compare custom objects?
I have a CoreData-based app that's many years old, so it's been a long time since I've actually dealt with CoreData. Over recent years, I've noticed that fetch requests aren't finding the object I know is in there. The entity is called Folder and has a single attribute named url, which is of type Transformable. The transformer is a custom one that converts a url into a dictionary with 2 keys; one is a security scoped bookmark created from the url, and the other is the original url in case the bookmark fails. The dictionary is then converted to NSData using NSKeyedArchiver securely. The reverseTransformedValue does the opposite; unarchives the data to a dict, attempts to resolve the bookmark back into the url. The fetch request is set up to fetch all Folder objects where: Custom Predicate: url == $THE_URL So is the fetch request comparing the NSData that's stored in the file and comparing that to $THE_URL after running it through the transformer to arrive at an NSData, or is it running each one through the transformer to get the underlying url and comparing those with $THE_URL? Could there be a better way to compare urls in Core Data, when the app is sandboxed and must use security scoped bookmarks?
0
0
211
Jul ’24
Tokenised text search in SwiftData help
The SwiftData predicate documentation says that it supports the contains(where:) sequence operation in addition to the contains(_:) string comparison but when I put them together in a predicate to try and perform a tokenised search I get a runtime error. Unsupported subquery collection expression type (NSInvalidArgumentException) I need to be able to search for items that contain at least one of the search tokens, this functionality is critical to my app. Any suggestions are appreciated. Also does anyone with experience with CoreData know if this is possible to do in CoreData with NSPredicate? import SwiftData @Model final class Item { var textString: String = "" init() {} } func search(tokens: Set<String>, context: ModelContext) throws -> [Item] { let predicate: Predicate<Item> = #Predicate { item in tokens.contains { token in item.textString.contains(token) } } let descriptor = FetchDescriptor(predicate: predicate) return try context.fetch(descriptor) }
2
1
455
Jul ’24
UIDocument related hang in OS code
Hi A user of my app has contacted me about a crash they’re getting. They’ve sent me some logs (see attached) but I’m having difficulty working out what the cause is as it looks like it’s a watchdog timeout that’s occurring inside OS code, not my application. I also can’t reproduce the crash locally. App background info: The app logs peoples skydives, each log can contain a lot of data (rotation rates, acceleration, location, speeds, etc) and is stored in a separate file. These files can be stored in an iCloud container so the logs can be viewed from different devices. I use CoreData to maintain a database of key metadata so I can list the jumps in the UI even if the file for a jump isn’t on the device. Occasionally I have to delete this database and rebuild it by loading each jump log file and getting a fresh copy of the metadata. EG this can happen if a new version of the app requires an additional metadata field in the database. Crash info: The crash looks like it’s happening rebuilding the database, so the app will be trying to download and open each jump log and add the records to the database. I’ve noticed the following odd things about the crash log, which might be a good place to start: There’s a huge number of threads in the “”UIDocument File Access” dispatch queue that are blocked It looks like there's exactly 512 threads blocked in this queue. Which makes me think its hitting a limit. Any idea why they are blocked? I don’t know why there are so many, The database rebuild is done from an operation queue with a max concurrency of 10. So I would expect at most 10 jump logs to be being opened at one time There seams to be two common stack trace patterns. Eg compare thread 1 and thread 5 in crash log 1. In both crash logs the main thread is blocked, but in different bits of OS code in the two crash logs. It looks like this is the cause of the watchdog failure, but I’m not sure what the common cause could be. Any ideas / help would be really appreciated. Thanks Tom NOTE: I had to cut down the crash logs so they were small enough to upload. Crash log 1 small.txt Crash log 2 small.txt
0
0
217
Jun ’24
SwiftData crash: PersistentModel.keyPathToString(keypath:)
I'm distributing an iOS (17.4+) and visionOS (1.2+) app via TestFlight that's using SwiftData. The most common crash by far is from SwiftData when deleting models from a context using a predicate (first snippet below), but so far I've been unable to reproduce it myself locally (second snippet below). I'm using SwiftData outside of SwiftUI views, via my own wrapper, and converting between my app models and SwiftData models. Does anyone have any ideas how I could potentially narrow this issue down (or reproduce), or know of any similar issues? Thanks! — Seb do { try context.transaction { context in let predicate = #Predicate<PersistedFeed> { $0.id == id } do { try context.delete(model: PersistedFeed.self, where: predicate) } catch { // .. Omitted for brevity } } } catch { // .. Omitted for brevity } Crash: Thread 0 Crashed: 0 libswiftCore.dylib 0x000000018dd558c0 _assertionFailure(_:_:file:line:flags:) + 264 (AssertCommon.swift:144) 1 SwiftData 0x000000022f7f323c static PersistentModel.keyPathToString(keypath:) + 1496 (DataUtilities.swift:0) 2 SwiftData 0x000000022f83312c PredicateExpressions.KeyPath.convert(state:) + 492 (FetchDescriptor.swift:394) 3 SwiftData 0x000000022f834a24 protocol witness for ConvertibleExpression.convert(state:) in conformance PredicateExpressions.KeyPath<A, B> + 16 (<compiler-generated>:0) 4 SwiftData 0x000000022f830a70 PredicateExpression.convertToExpressionOrPredicate(state:) + 724 (FetchDescriptor.swift:203) 5 SwiftData 0x000000022f831874 PredicateExpression.convertToExpression(state:) + 36 (FetchDescriptor.swift:217) 6 SwiftData 0x000000022f83b6c8 PredicateExpressions.Equal.convert(state:) + 328 7 SwiftData 0x000000022f8360ec protocol witness for ConvertibleExpression.convert(state:) in conformance PredicateExpressions.Equal<A, B> + 64 (<compiler-generated>:0) 8 SwiftData 0x000000022f830a70 PredicateExpression.convertToExpressionOrPredicate(state:) + 724 (FetchDescriptor.swift:203) 9 SwiftData 0x000000022f82fd60 PredicateExpression.convertToPredicate(state:) + 28 (FetchDescriptor.swift:224) 10 SwiftData 0x000000022f82edb4 nsPredicate<A>(for:) + 956 (FetchDescriptor.swift:88) 11 SwiftData 0x000000022f807c2c ModelContext.delete<A>(model:where:includeSubclasses:) + 596 (ModelContext.swift:1846) 12 SwiftData 0x000000022f81994c dispatch thunk of ModelContext.delete<A>(model:where:includeSubclasses:) + 56
0
1
277
Jun ’24
Using NSFetchedResultsController with viewContext seems to have bad performance
Hello! Our team have been using a NSFetchedResultsController with viewContext for list UI. But we found some UI Hang logs, and I'm guessing that it happens because of Faulting in viewContext. The main thread call stacks in the logs look like below. 0 libsystem_kernel.dylib 0x00000001f378dbcc kevent_id + 8 1 libdispatch.dylib 0x00000001b4047b0f _dispatch_kq_poll + 227 2 libdispatch.dylib 0x00000001b40484df _dispatch_event_loop_wait_for_ownership + 435 3 libdispatch.dylib 0x00000001b4034983 __DISPATCH_WAIT_FOR_QUEUE__ + 339 4 libdispatch.dylib 0x00000001b403454b _dispatch_sync_f_slow + 147 5 CoreData 0x00000001b42859b3 _perform + 203 6 CoreData 0x00000001b4372767 -[NSManagedObjectContext+ 1275751 (_NestedContextSupport) newValuesForObjectWithID:withContext:error:] + 163 7 CoreData 0x00000001b424cf87 _PFFaultHandlerLookupRow + 275 8 CoreData 0x00000001b424cbbf _PF_FulfillDeferredFault + 191 9 CoreData 0x00000001b424cab7 _pvfk_header + 167 10 CoreData 0x00000001b424c9d7 _sharedIMPL_pvfk_core + 31 11 Works 0x000000010445517b closure #1 in static MailUIMailFactory.make(mail:needFolderName:) + 26530171 (MailUIMailFactory.swift:109) ... 0 libsystem_kernel.dylib 0x00000001dbd4254c kevent_id + 8 1 libdispatch.dylib 0x000000019b7057d3 _dispatch_kq_poll + 227 2 libdispatch.dylib 0x000000019b7061bb _dispatch_event_loop_wait_for_ownership + 435 3 libdispatch.dylib 0x000000019b6f2593 __DISPATCH_WAIT_FOR_QUEUE__ + 339 4 libdispatch.dylib 0x000000019b6f215b _dispatch_sync_f_slow + 147 5 CoreData 0x000000019b94f24b _perform + 203 6 CoreData 0x000000019ba3c41b -[NSManagedObjectContext+ 1274907 (_NestedContextSupport) newValueForRelationship:forObjectWithID:withContext:error:] + 167 7 CoreData 0x000000019b914387 -[NSFaultHandler retainedFulfillAggregateFaultForObject:andRelationship:withContext:] + 391 8 CoreData 0x000000019b9118bf -[_NSFaultingMutableSet willReadWithContents:] + 391 9 CoreData 0x000000019b91e663 -[_NSFaultingMutableSet count] + 23 10 Foundation 0x0000000192dbeb3f -[NSSet+ 7609151 (NSKeyValueSorting) sortedArrayUsingDescriptors:] + 55 11 Works 0x000000010249ec1f specialized static MailUIMailFactory.make(mail:needFolderName:) + 27470879 (MailUIMailFactory.swift:102) ... We just use NSFetchedResultsController's fetchedObjects in table view's cellForRowAt method, and make a new model by MailUIMailFactory.make. So we're thinking that we need to initialize NSFetchedResultsController with bg Context. What you guys think? Do I avoid using viewContext in heavy UI?
0
0
237
Jun ’24
SwiftData fatal error "Never access a full future backing data"
My app started crashing a ton with Xcode 16 beta 1 / iOS 18 because of "Thread 1: Fatal error: Never access a full future backing data". I was hoping this would be resolved with beta 2, but unfortunately this is not the case. I'm having a tough time reproducing this bug in a small sample project – I'd appreciate any hints as to what might be causing this. Full error: Thread 1: Fatal error: Never access a full future backing data - PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(url: x-coredata://10A5A93C-DC7F-40F3-92DB-F4125E1C7A73/MyType/p2), implementation: SwiftData.PersistentIdentifierImplementation) with Optional(3BF44A2D-256B-4C40-AF40-9B7518FD9FE6)
7
6
616
1w
How to embed SwiftData model container in a custom file package document type
Hi all, I have done a lot of research on this but am not able to come up with a workable solution. Background: I am trying to make an universal app on macOS/iOS that organizes media (image/video/pdf); think of its functionality like Apple's Photos app. So for my app document type, I would have my custom file package and within the package folder, there would be a SwiftData model container file and folders to hold user media. Approaches taken: DocumentGroup with SwiftData model then write directly into the file package In my App scene, I create document by having DocumentGroup(editing: .customDocument, migrationPlan: CustomMigrationPlan.self). This will create a document with a model container with my SwiftData model. And when I need to add media files into the document, I get the URL of the document, then use FileManager to write the file into the desired folder in the document. The result is that the media file is saved in the file package but then the SwiftData container is corrupted (all model data is reset to empty.) I am now trying to: 2. DocumentGroup with custom file package then try to embed SwiftData container In my current approach, I would create a document by having DocumentGroup(newDocument: CustomFileDocument()). I have custom FileDocument and FileWrapper. But the problem is I don't know how to embed a SwiftData container into my FileDocument. Is it possible to create a SwiftData model container when my FilerWrapper initialize? I can't figure out how to do this. Can anyone please advice on how I should accomplish this? Or if maybe I am looking at this problem wrongly? Do I need to use AppKit/UIKit with Core Data because it's currently not possible with SwiftUI/SwiftData? Thank you so much for reading and any input is greatly appreciated.
0
0
241
Jun ’24