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.

Core Data Documentation

Posts under Core Data tag

224 Posts
Sort by:
Post not yet marked as solved
0 Replies
173 Views
Hello I have a TestFlight tester getting a random repeated crash when the app is interacting with core data. Every time it crashes we get the call stack like below from line 6 stating -NSManagedObject _processRecentChanges. Searching for _sharedIMPL_setvfk_core it seems to indicate a multithreading issue but my managedObjectContext is initialized with main queue concurrency. - (NSManagedObjectContext *)managedObjectContext { if (managedObjectContext != nil) { return managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSMainQueueConcurrencyType]; [managedObjectContext setPersistentStoreCoordinator:coordinator]; } return managedObjectContext; } When I pulled the cashpoint in to the Xcode project everything appears to be running on the main thread. I can't seem to find documentation on what might be causing the issue. Any pointers would be appreciated. The app is compiled on Xcode 15 targeting iOS 15. Users device is iOS 17.3.1.
Posted
by cjhuber.
Last updated
.
Post not yet marked as solved
1 Replies
205 Views
Here is my basic problem. The app itself builds without issue, but when I simulate I get the following log in the debug console. The app also force closes when the Save function is selected with these errors. The app is a simple form which saves the data to a CoreData entity. It will do more (full CRUD) later after I deal with this particular issue. I have checked and rechecked class names, spelling issues, case sensitivities. I can not seem to find the issue. error: No NSEntityDescription in any model claim the NSManagedObject subclass 'App.Entity' so +entity is confused. Have you loaded your NSManagedObject Model yet? Also: error: +[App.Entity entity] Failed to find a unique match for an NSEntityDescription to a managed object subclass
Posted
by AtreuIT.
Last updated
.
Post not yet marked as solved
2 Replies
377 Views
Hi, I am running into a reproducible SwiftUI List crash when using @FetchRequest based on an @ObservedObject. The crash happens only when deleting the last item in a section. All other deletes and inserts (that I've tested so far) seem to work fine. I'm hoping I can figure out why this happens, and if there is a workaround that I can use. The crash looks something like this: *** Assertion failure in -[SwiftUI.UpdateCoalescingCollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:collectionViewAnimator:], UICollectionView.m:10643 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete item 17 from section 0 which only contains 17 items before the update' The setup: I have a Core Data one-to-many relationship ... in this case, a Contact that has many Notes saved to it. When you select a Contact from a list, it goes to a ContactDetailsView which has some details of the contact, and a list of 'notes' saved to it. struct ContactDetailsView: View { @Environment(\.managedObjectContext) private var viewContext @ObservedObject var contact: Contact // -> making this 'let' works var body: some View { VStack (alignment: .leading) { Text(contact.firstName ?? "") Text(contact.lastName ?? "") NotesListView(contact: contact) Button("Add Test Notes") { let note1 = Notes(context: viewContext) note1.noteMonth = "Feb" note1.noteDetails = "Test1" note1.noteDate = Date() note1.contact = contact try? viewContext.save() } } .padding() } } The NotesListView has a @SectionedFetchRequest (the error is the same if I use a regular @FetchRequest). struct NotesListView: View { @Environment(\.managedObjectContext) private var viewContext @ObservedObject var contact: Contact // -> making this 'let' works @SectionedFetchRequest var sectionNotes: SectionedFetchResults<String, Notes> @State private var selectedNote: Notes? init(contact: Contact) { self.contact = contact let fetchRequest = Notes.fetchRequest() fetchRequest.predicate = NSPredicate(format: "contact == %@", contact) fetchRequest.sortDescriptors = [NSSortDescriptor(key: "noteDate", ascending: true)] _sectionNotes = SectionedFetchRequest(fetchRequest: fetchRequest, sectionIdentifier: \.noteMonth!) } var body: some View { List (selection: $selectedNote){ ForEach(sectionNotes) { section in Section(header: Text(section.id)) { ForEach(section, id: \.self) { note in VStack (alignment: .leading){ if let details = note.noteDetails { Text(details) } } .swipeActions { Button(role: .destructive, action: { delete(note: note) }, label: { Image(systemName: "trash") }) } } } } } } public func delete(note: Notes){ viewContext.delete(note) do{ try viewContext.save() } catch{ print("delete note error = \(error)") } } } Calling the delete method from swipe-to-delete always crashes when the note is the last item on the list. In the ContactDetailsView, and it's child view NotesListView I have marked the 'var contact: Contact' as an @ObservedObject. This is so that changes made to the contact can be reflected in the ContactDetailsView subviews (the name fields here, but there could be more). If I make both of these properties let contact: Contact, I don't get a crash anymore! But then I lose the 'observability' of the Contact, and changes to the name won't reflect on the Text fields. So it seems like something about @ObservedObject and using a List in its subviews is causing this problem, but I'm not sure why. Maybe the @ObservedObject first reloads its relationship and updates the view, and then the FetchRequest also reloads the List, causing a double-delete? But it surprisingly only happens for the last element in the list, and not otherwise. Another option I considered was losing the @FetchRequest and using contact.notes collection to drive the list. But isn't that inefficient compared to a @FetchRequest, especially with sorting and filtering, and loading the list of 1000s of notes? Any suggestions for a work-around are welcome. The full crash looks something like this: *** Assertion failure in -[SwiftUI.UpdateCoalescingCollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:collectionViewAnimator:], UICollectionView.m:10643 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete item 17 from section 0 which only contains 17 items before the update' *** First throw call stack: ( 0 CoreFoundation 0x0000000180491128 __exceptionPreprocess + 172 1 libobjc.A.dylib 0x000000018008412c objc_exception_throw + 56 2 Foundation 0x0000000180d1163c _userInfoForFileAndLine + 0 3 UIKitCore 0x0000000184a57664 -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:collectionViewAnimator:] + 4020 4 UIKitCore 0x0000000184a62938 -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:animator:animationHandler:] + 388 5 SwiftUI 0x00000001c51f0c88 OUTLINED_FUNCTION_249 + 5648 .... 39 TestCoreDataSwiftUISections 0x000000010248c85c $s27TestCoreDataSwiftUISections0abcdE3AppV5$mainyyFZ + 40 40 TestCoreDataSwiftUISections 0x000000010248c998 main + 12 41 dyld 0x0000000102625544 start_sim + 20 42 ??? 0x00000001027560e0 0x0 + 4336214240 43 ??? 0x2103000000000000 0x0 + 2378745028181753856
Posted
by zulfishah.
Last updated
.
Post not yet marked as solved
11 Replies
7.0k Views
Any insights on how to incorporate CloudKit (or CoreData) in the WidgetKit extension? Where in the WidgetKit api do I make the asynchronous call to load the data to be available for the TimelineProvider?
Posted
by cristosv.
Last updated
.
Post not yet marked as solved
1 Replies
198 Views
I have set a core data structure based on two entities : first entity is "Mot" (Word) with one String attribute "graphie" (spelling) and one ToOne relationship "definition" with the second entity. second entity is "Definition" that has one String attribute "enonce" (statement) and on ToMany relationship "mot" with entity Mot. One word can have several spellings but only one definition. I managed to load several rows of data and now, when I select one word I want to display all the spellings, which means all "Mot" that have the same definition. In my content view I have a List based on a request: @Environment(\.managedObjectContext) private var viewContext @FetchRequest(entity: Mot.entity(), sortDescriptors: [NSSortDescriptor(key: "graphie", ascending: true)]) private var mots: FetchedResults<Mot> var body: some View { NavigationView { ... List { ForEach(mots) { (mot: Mot) in HStack { Text(mot.graphie ?? "Non trouvé") Spacer() Text(mot.definition!.enonce ?? "Non trouvé") } .onTapGesture { motAffiche = mot tfMot = mot.graphie ?? "Not found" tfDefinition = mot.definition?.enonce ?? "Not found" tfOrthoAlt = returnOrthoAlt(mot: mot) } } } the function returnOrthoAlt(mot) is supposed to return a string with all spellings separated by commas. What is working for the moment, but not satisfactory is the following code for that function private func returnOrthoAlt(mot: Mot) -> String { var ort = [String]() for elem in mots { if elem.definition!.enonce! == mot.definition!.enonce! && elem != mot { ort.append(elem.graphie!) let defObjId = elem.definition!.objectID.uriRepresentation() print("\(elem.graphie!) def: \(elem.definition!.enonce!) \(defObjId) ") } } return if !ort.isEmpty { ort.joined(separator: ", ")} else {""} }: I am going through the table 'mots' of FetchedResults to find those that have the same definition as the current 'mot'. What I find not satisfactory is that I am comparing the 'mot.definition.enonce' of each Mot, which is not supposed to be unique, instead of 'mot.definition' directly, which did not work. The objects 'mot.definition' are obviously not equal (neither with == nor with === operators). Also I tried to retrieve the reverse relation directly with 'mot.definition.mot' but that returned a NSSet which, converted to a set seems to contain only one object, that is 'mot' itself. One possibility of course, would be to ad a unique Id to the entity 'Definition' but I seem to understand that this is not the recommended practice, the more so as swift does not provide system generated id. What do I miss in the core data concept ? Can someone help me out ?
Posted
by SimonWin.
Last updated
.
Post not yet marked as solved
0 Replies
235 Views
I want to display a list of 'contacts' in my app, loaded from a local Core Data sqlite database. Currently, I use UIKit, and with UITableView's cell reuse, even with 5000+ rows, the memory usage is great ... it loads at about 80MB and stays around that no matter how much I scroll up or down the list. I implemented the same list with SwiftUI List, and the memory usage while scrolling is very different ... the initial load is about the same, but each time I go down the whole list, it adds 20-30MB to the memory usage (according to Xcode). Is this a side-effect of using SwiftUI's List, or am I doing something wrong here? Here's the implementation: struct CJContactsListView: View { @SectionedFetchRequest var sectionContacts: SectionedFetchResults<String, Person> init() { let fetchRequest = Person.allContactsFetchRequest() _sectionContacts = SectionedFetchRequest(fetchRequest: fetchRequest, sectionIdentifier: \.normalizedSectionLetter!, animation: .default) } var body: some View { List { ForEach(sectionContacts) { section in Section(header: Text(section.id)) { ForEach(section) { person in CJContactsListLabelRowView(person: person) } } } } .listStyle(.plain) } } struct CJContactsListLabelRowView: View { @ObservedObject var person: Person var body: some View { HStack (alignment: .center, spacing: 8) { VStack (alignment: .leading){ if let displayName = person.displayName { Text(displayName).font(.headline) } if let companyName = person.companyName { Text(companyName).font(.subheadline).foregroundColor(.secondary) } } } } } extension Person: Identifiable { public var id: String { return self.objectID.uriRepresentation().absoluteString } public static func allContactsFetchRequest() -> NSFetchRequest<Person> { let request = Person.fetchRequest() request.sortDescriptors = Person.makeSortDescriptors() request.predicate = NSPredicate(format: "(isContactArchived == nil || isContactArchived == 0)") request.fetchBatchSize = 100 request.relationshipKeyPathsForPrefetching = ["tags"] return request } } There isn't a visible performance issue in my testing (i.e. I don't see a 'stutter' when scrolling really fast), but the memory profile growing does concern me, especially when this isn't a problem in UIKit. I've tested the "Earthquakes" sample project from Apple and it seems to display the same issue (memory profile grows substantially as the user scrolls down the list). Would love to know if there's a way to avoid this issue.
Posted
by zulfishah.
Last updated
.
Post not yet marked as solved
1 Replies
198 Views
Is there any app out there that lets you browse through a CoreData database? When I first started to learn Swift, an app called Liya seemed to work. But alas, no longer. it would just make it easier if there was anything out there that let you browse the data directly. Thanks
Posted
by SergioDCQ.
Last updated
.
Post marked as solved
1 Replies
310 Views
The Statement I have a SwiftUI app that uses CoreData and iCloud with NSPersistentCloudKitContainer prepared for beta testing via TestFlight. The app utilizes iCloud solely as a private database for user data across different devices. The app doesn't use any public or shared database. According to Apple's guidelines, deploying the development schema to production is necessary before submitting to the App Store: Before you publish your app, you must deploy the development schema to the production environment to copy over its record types, fields, and indexes. I am aware that once deployed to production, it's impossible to delete or modify any types or fields: To prevent conflicts, you can’t delete record types or fields that are already in production. Every time you deploy the development schema, its additive changes merge into the production schema. The Questions: When is the appropriate time to deploy the schema to production? Should it be done before beta testing via TestFlight, or is it sufficient to deploy it just before releasing the app on the App Store after beta testing? If the schema needs to be deployed before beta testing, does that mean I won't be able to reset the schema if testers discover critical bugs related to the data model, and I'll be compelled to delete or modify any types or fields? Thank you in advance for any responses!
Posted
by Hollycene.
Last updated
.
Post not yet marked as solved
3 Replies
636 Views
I'm trying to add two more data models SectionsSD andArticles SD to an existing project using SwiftData where I had one model and am running into a variety of CoreData errors when I try to run my app. I am running Xcode 15.2 and the latest iOS simulator at iOS 17.2 Here is my container let container: ModelContainer = { let schema = Schema([ LocationData.self, SectionsSD.self, ArticlesSD.self ]) let container = try! ModelContainer(for: schema, configurations: []) return container }() After I add these two models I get the following errors and I can't load data into the SectionsSD and ArticlesSD models. If I comment out my LocataionData model that works w/o error or if I run just LocationData it runs without error but run all together and I get the following errors in the log: error: Error: Persistent History (11) has to be truncated due to the following entities being removed: ( SectionsSD, ArticlesSD ) CoreData: error: Error: Persistent History (11) has to be truncated due to the following entities being removed: ( SectionsSD, ArticlesSD ) warning: Warning: Dropping Indexes for Persistent History CoreData: warning: Warning: Dropping Indexes for Persistent History warning: Warning: Dropping Transactions prior to 11 for Persistent History CoreData: warning: Warning: Dropping Transactions prior to 11 for Persistent History warning: Warning: Dropping Changes prior to TransactionID 11 for Persistent History Any advice here would be appreciated. These are initial models so migration is not really a need yet. Seems to just **** if you add more models.
Posted Last updated
.
Post not yet marked as solved
0 Replies
198 Views
In my recent endeavor, I aimed to introduce new Fetch Index Elements to the Core Data model of my iOS application. To achieve this, I followed a process of lightweight migration, detailed as follows: Navigate to Editor > Add Model Version to create a new version of the data model. Name the new version with a sequential identifier (e.g., MyAppModelV3.xcdatamodel) based on the naming convention of previous models. Select the newly created version, MyAppModelV3.xcdatamodel, as the active model. Mark this new version as the "Current" model in the Xcode properties panel on the right. In the new version of the model, MyAppModelV3.xcdatamodel, and add the new Fetch Index Elements there. Also, insert "v3" in the Versioning Hash Modifier field of affected entity, to indicate this modification. Upon reflection, I realized that creating a new version of the xcdatamodel might not have been necessary for this particular case. However, it appears to have caused no adverse effects on the application's functionality. During testing, I executed the application in a simulated environment, initially running an older version of the app to inspect the database content with SQLite DB Browser. I then upgraded to the latest app version to verify that the migration was successfully completed without causing any crashes. Throughout this testing phase, I employed the -com.apple.CoreData.MigrationDebug 1 flag to monitor all SQL operations, ensuring that indexes were appropriately dropped and recreated for the affected entity. Following thorough testing, I deployed the update to production. The majority of users were able to upgrade to the new app version seamlessly. However, a small fraction reported crashes at startup, indicated by the following error message: Fatal error: Unresolved error Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={NSUnderlyingError=0x2820ad3e0 {Error Domain=NSCocoaErrorDomain Code=134100 "The managed object model version used to open the persistent store is incompatible with the one that was used to create the persistent store." UserInfo={metadata={ NSPersistenceFrameworkVersion = 1338; NSStoreModelVersionChecksumKey = "qcPf6+DfpsPrDQ3j1EVXcBIrFe1O0R6IKd30sJf4IrI="; NSStoreModelVersionHashes = { NSAttachment = {length = 32, ... Strangely, the only way I could replicate this issue in the simulator was by running the latest version of the app followed by reverting to an older version, a scenario unlikely to occur in a real-world setting. This raises the question: How could this situation arise with actual users, considering they would typically move from an old to a new version rather than the reverse? I am reaching out to the community for insights or advice on this matter. Has anyone else encountered a similar problem during the Core Data migration process? How did you resolve it?
Posted
by yccheok.
Last updated
.
Post marked as solved
1 Replies
358 Views
Hey all. I've been rewriting my Objective-C app in SwiftUI (it's going well, thanks!) and I'm hitting this issue that I thought I'd solved ages ago. I have version 5.1 of my original ObjC app using version 11 of the Core Data model. I've created a new version 12, added a couple of new attributes, and created a mapping model from 11 to 12. The fields I've added are booleans, and I've set them to have a default value of NO so that new entries will automatically get NO, but there are existing records that don't have that field at all, and I'd like them to also get NO (or YES, depending on something in the other fields, but I haven't figured out how to do that yet). This is how Core Data is set up in the new Swift target: public extension URL { // Returns a URL for the given app group and database pointing to the sqlite database static func storeURL(for appGroup: String, databaseName: String) -> URL { guard let fileContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup)?.appending(path: kCoreDataFolder) else { logger.error("Shared file container could not be created.") fatalError("CoreData: Shared file container could not be created.") } return fileContainer.appendingPathComponent("\(kCoreDataModel)") } } // MARK: - Persistence Controller struct CoreData { static let shared = CoreData() let container: NSPersistentContainer init() { let storeURL = URL.storeURL(for: kAppGroup, databaseName: kCoreDataModel) let storeDescription = NSPersistentStoreDescription(url: storeURL) container = NSPersistentContainer(name: kCoreDataModel) container.persistentStoreDescriptions = [storeDescription] container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { logger.error("Failed to initialise Managed Object Model from url: \(storeURL), with error: \(error), \(error.userInfo)") fatalError("CoreData: Failed to initialise Managed Object Model from url: \(storeURL), with error: \(error), \(error.userInfo)") } }) container.viewContext.automaticallyMergesChangesFromParent = true } When I run the old app on the Simulator it adds some demo data (using model v11), and the app functions properly. If I then install the new version - using v12 - it fails with a Core Data error because it couldn't migrate the data. (Apologies, I cannot get the exact error at the moment as I'm part-way through redoing some other stuff and the app won't build.) I've read somewhere that "When we use the NSPersistentContainer class to create and manage the Core Data stack, we don't need to do any additional setup work, the lightweight migration is automatically activated for us." But if that's the case, why does my app crash? I'll try and get the exact error for you... How do I implement lightweight migration in Swift? This page suggests creating a persistent coordinator and adding a couple of options, but I can't quite figure out how to do that with the code I already have, and each time I try it seems to beat the original store so I keep going back to the above code because it works.
Posted
by darkpaw.
Last updated
.
Post not yet marked as solved
0 Replies
231 Views
I've defined 'public' and 'private' configurations in CoreData and configured the 'public' configuration to be handled in the CloudKit publicDB. The two configurations contain disjoint sets of NSManagedObject entity types. Some of the entities in the private configuration reference an entity in the public configuration using a UUID; thereby avoiding cross-configuration CoreData relationships. Avoiding this is a requirement of CoreData + CloudKit. Now, since the UUID is meant to point to an object, in the awakeFromFetch() method I decided to fill in a transient property. No go. Even for a transient property there cannot be a cross-configuration relationship. Why? Is there a way to avoid this constraint? The cost of not having a transient property is to do a fetch of the object based on the UUID every time it is needed. Is this something that one should never worry about?
Posted
by GoZoner.
Last updated
.
Post not yet marked as solved
1 Replies
355 Views
I've had a couple SwiftData crashes in production I can’t figure out. Both times the crash happened when setting a child Model to a parent Model. The child should already be inserted in the context before setting on the parent. But a crash still happens at CoreData: _PFManagedObject_coerceValueForKeyWithDescription. The child does have some Codable properties, but they’re just a couple enum. This isn’t a super common crash either. I can’t seem to reproduce. Any ideas? Simplified models: @Model final class Note { @Relationship(deleteRule: .nullify, inverse: \CoffeeBag.notes) var coffeeBag: CoffeeBag? } @Model final class CoffeeBag { var notes: [Note]? = [] } And the crash stack trace: Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Termination Reason: SIGNAL 6 Abort trap: 6 Terminating Process: MyApp [19953] Triggered by Thread: 0 Last Exception Backtrace: 0 CoreFoundation 0x1a2bbe678 __exceptionPreprocess + 164 (NSException.m:249) 1 libobjc.A.dylib 0x19ae63c80 objc_exception_throw + 60 (objc-exception.mm:356) 2 CoreData 0x1aad117a8 _PFManagedObject_coerceValueForKeyWithDescription + 1576 (NSManagedObject.m:0) 3 CoreData 0x1aad110e8 _sharedIMPL_setvfk_core + 180 (NSManagedObject_Accessors.m:1491) 4 SwiftData 0x23d9359c8 static _DefaultBackingData.setRelationship(value:key:managedObject:) + 360 (BackingData.swift:364) 5 SwiftData 0x23d9388fc closure #1 in static _DefaultBackingData.setValue(key:managedObject:newValue:) + 256 (BackingData.swift:215) 6 SwiftData 0x23d8d6e4c thunk for @callee_guaranteed () -> () + 28 (<compiler-generated>:0) 7 SwiftData 0x23d8d6e74 thunk for @escaping @callee_guaranteed () -> () + 28 (<compiler-generated>:0) 8 CoreData 0x1aad087c4 developerSubmittedBlockToNSManagedObjectContextPerform + 156 (NSManagedObjectContext.m:3983) 9 CoreData 0x1aad08698 -[NSManagedObjectContext performBlockAndWait:] + 208 (NSManagedObjectContext.m:4094) 10 SwiftData 0x23d933758 static _DefaultBackingData.setValue(key:managedObject:newValue:) + 360 (BackingData.swift:211) 11 SwiftData 0x23d9383b0 _DefaultBackingData.setValue<A>(forKey:to:) + 232 (BackingData.swift:174) 12 SwiftData 0x23d93b328 protocol witness for BackingData.setValue<A>(forKey:to:) in conformance _DefaultBackingData<A> + 24 (<compiler-generated>:0) 13 SwiftData 0x23d8f32dc PersistentModel.setValue<A>(forKey:to:) + 288 (PersistentModel.swift:102) 14 MyApp 0x100f166d4 closure #1 in MyAppSchemaV6.Note.coffeeBag.setter + 132 (@__swiftmacro_7MyApp0aB8SchemaV6O4NoteC9coffeeBag18_PersistedPropertyfMa_.swift:15) 15 MyApp 0x100f22864 partial apply for closure #1 in MyAppSchemaV6.Note.coffeeBag.setter + 16 (<compiler-generated>:0) 16 libswiftObservation.dylib 0x247ff21b8 ObservationRegistrar.withMutation<A, B, C>(of:keyPath:_:) + 100 (ObservationRegistrar.swift:365) 17 MyApp 0x100f21c28 MyAppSchemaV6.Note.coffeeBag.setter + 172 (@__swiftmacro_7MyApp0aB8SchemaV6O4NoteC9coffeeBag18_PersistedPropertyfMa_.swift:14) 18 MyApp 0x100f21c28 closure #1 in closure #1 in closure #4 in BrewSummaryView.body.getter + 1076 (BrewSummaryView.swift:116) 19 SwiftUI 0x1a81b77b0 ButtonAction.callAsFunction() + 260 (Button.swift:598) // the rest is trimmed off to fit...
Posted
by jonduenas.
Last updated
.
Post marked as solved
6 Replies
1.1k Views
I have an app that is already running with CoreData, and I want to allow the users to upload their data to iCloud so, in the case they need to delete their apps or change devices, they don't lose it. Every time the app is opened, there is a synchronization that happens between CoreData and a JSON file fixture, in order to fill the app with its base values (creating NSManagedObject instances from the aforementioned fixture). Before the iCloud sync, the CoreData model had some constraints for different entities, to enforce uniqueness, but these had to be stripped since CloudKit doesn't support them. Most of these constraints were basically ids that came from the JSON and represent an item in our Firebase database. Given that, I want to make the underlying CKRecord.id the same as these ids, so I can avoid the situation where, if a person open the app in a second device, the fixture data is repeated, since the fixture runs before the sync with the iCloud happens. Is that possible? Any help would be appreciated.
Posted Last updated
.
Post not yet marked as solved
1 Replies
327 Views
What interfaces do I use to propagate a CloudKit change in a shared zone to a notification/badge to all participants in the shared zone? Assume I have a 'League' that is the root object in a shared zone and that N Players are members of the league. One of the players, the 'organizer', schedules a 'Game' that is open to any of the players. When the organizer creates the game (in the league's shared zone) and it is mirrored in CloudKit, how can the other players see it (as a timely notification)? I already observe .NSPersistentStoreRemoteChange on NSPersistentStoreCoordinator and NSPersistentCloudKitContainer.eventChangedNotification on NSPersistentCloudKitContainer. Are these delivered in the background? Can/Should they generate a 'local/remote' notification for handling at the AppDelegate level? How? Do I need to use a CKDatabaseSubscription looking for CD_Game records directly? (I'd rather not; because then I'd have a potential race between the remote iCloud database(s) and the local CoreData)
Posted
by GoZoner.
Last updated
.
Post not yet marked as solved
0 Replies
208 Views
I'm sorta baffled right now. I am trying to wonder how I might detect a updated SQL Store in an older app. have a baseline app, and create a SQL-based repository in an updated app, change the model and verify that you can see the updated model version. Using lightweight migration re-run the older app (which will inherit the newer SQL repository). YIKES - no error when creating the NSPersistenStoreCoordinator! Nothing in the metadata to imply the store is newer than the model: [_persistentStoreCoordinator metadataForPersistentStore:store] My question: is there any way to detect this condition? David
Posted
by dhoerl.
Last updated
.
Post marked as solved
1 Replies
234 Views
I developing simple app to calculate personal money income and consumption. I use CORE DATA to save my model. The models consists of this CDCatalogWallet var name: String var ref: String CDCatalogStateIncome var name: String var ref: String CDDocumentIncome var ref: String var wallet: CDCatalogWallet (relationship has one) var states_: CDDocumentIncomeState (relationship has many) CDDocumentIncomeState var cdCatalogStateIncome: CDCatalogStateIncome (relationship has one) var document: CDDocumentIncome (relationship has one) CDDocumentIncome hasMany -> CDDocumentIncomeState hasOne -> CDCatalogStateIncome The bug shows when we pushing CDDocumentIncomeState view The model is simple. The CDDocumentIncome has relationship property cdCatalogStateIncome (relationship many). We open view with CDDocumentIncome and want to add new cdCatalogStateIncome to CDDocumentIncome Then we open view with new cdCatalogStateIncome. On this screen cdCatalogStateIncome has a relationship to CDDocumentIncomeState. But view does not opened. Console constantly print messages DocumentIncomeStateDetailView: @self changed. DocumentIncomeStateDetailView: @self changed. DocumentIncomeStateDetailView: @self changed. DocumentIncomeStateDetailView: @self changed. Also memory increase constantly and very fast. I understand that the view renders constantly. But I cannot figure out what cause a bug. The full code is available on github Github Project
Posted
by sapgv.
Last updated
.
Post not yet marked as solved
0 Replies
395 Views
How can one avoid SwiftUI processing of views referencing a CoreData entity that has been deleted? I've taken to 'wrapping' View body's with the following: struct ManagedObjectDeleteWrapper<Object, Root> : View where Object : NSManagedObject, Root : View { var object: Object var root: (Object) -> Root var body: some View { Group { if object.isFault { EmptyView() } else { root (object) } } } } like such: struct GameView: View { @EnvironmentObject private var game: Game var body: some View { ManagedObjectDeleteWrapper (object: game) { _ in // Show `game` attributes and relationships } } } but this has become quite tedious. It is not as simple a wrapping the 'top-level' view (in my App, three or so TabViews), but one must wrap multiple subviews if they also reference game. How can I approach this short of using game.isFault or ManagedObjectDeleteWrapper everywhere? I'm cognizant that perhaps my 'view flow' is leading to this problem; is there a generic approach to view hierarchies that avoids the problem? Maybe 'only delete an object from a list view; only show the object content view a navigation link on that list view' ? My current design has three tab views showing game content and one tab showing 'competitions' (as set of games); a game is deleted from the competitions tab... and if that game is being displayed all the other tab views are invalid.
Posted
by GoZoner.
Last updated
.
Post not yet marked as solved
5 Replies
844 Views
I've been trying to build an example of NSStagedMigrationManager from some Core Data migration tests to replace a custom migration manager solution I'd constructed, without much success. The Core Data model has seven model versions. Most support lightweight migration, but two of the migrations in the middle of the sequence used NSMappingModel. In the first beta, just attempting to construct an NSStagedMigrationManager from the series of stages failed with an unrecognized selector. That no longer happens in b4, but I now get an error that "Duplicate version checksums across stages detected." If I restrict myself to just the first three versions of the model (that only require lightweight migration), I can build the migration manager. But if I attempt to use it to migrate a persistent store, it fails somewhere in NSPersistentStoreCoordinator with a nilError. The documentation is almost nonexistent for this process, and the WWDC session that introduced it isn't much more than a breezy overview. So maybe I'm holding it wrong? (And, yes: FB12339663)
Posted
by 610.
Last updated
.
Post not yet marked as solved
0 Replies
311 Views
From core data I generate data for map marker pins. When user selects a marker pin I display the data in a popup label with multiple rows, when I click on the pin. This is working for one marker pin. Now, I need to iterate over a list and generate several of those markers each with unique popup label data. The code: struct MapView: UIViewRepresentable { var annotationOnTap: (_ title: String) -> Void @Binding var pins: [GpsData.MyEndPt] let key: String private static var mapViewStore = [String : MKMapView]() func makeUIView(context: Context) -> MKMapView { if let mapView = MapView.mapViewStore[key] { mapView.delegate = context.coordinator return mapView } let mapView = MKMapView(frame: .zero) mapView.delegate = context.coordinator MapView.mapViewStore[key] = mapView return mapView } func updateUIView(_ uiView: MKMapView, context: Context) { uiView.addAnnotations(pins) } func makeCoordinator() -> MapCoordinator { MapCoordinator(self) } final class MapCoordinator: NSObject, MKMapViewDelegate { var parent: MapView init(_ parent: MapView) { self.parent = parent } func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { let PINID:String = "MyEndPoint" var mPin: MKMarkerAnnotationView? = nil let subtitleView = UILabel() subtitleView.font = subtitleView.font.withSize(12) subtitleView.numberOfLines = 0 if (mPin == nil ) { mPin = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: PINID) mPin?.canShowCallout = true } else{ mPin?.annotation = annotation } mPin?.leftCalloutAccessoryView = nil let btn = UIButton(type: .detailDisclosure) mPin?.rightCalloutAccessoryView = btn let zip:String = "77065" let formattedSalesStr:String = "100" let totalTargetText:String = "500" let paddedLoad = formattedSalesStr.padding(toLength: 50, withPad: " ", startingAt: 0) let paddedCapacity = totalTargetText.padding(toLength: 50, withPad: " ", startingAt: 0) subtitleView.text = "Total sales: " subtitleView.text! += paddedLoad subtitleView.text! += " \r\n" subtitleView.text! += "Total Target: " subtitleView.text! += paddedCapacity subtitleView.text! += " \r\n" subtitleView.text! += paddedzip mPin!.detailCalloutAccessoryView = subtitleView return mPin! } } } As you can see in the above method I have hardcoded values for my popup marker label. So I tried to iterate over the @Binding pins, populate each mPin, and return an array of MKAnnotationView, like this: func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> [MKAnnotationView] { let PINID:String = "MyEndPoint" var i:Int = 1 var mPins = [MKAnnotationView]() for detail in self.parent.pins { var mPin: MKMarkerAnnotationView? = nil let subtitleView = UILabel() subtitleView.font = subtitleView.font.withSize(12) subtitleView.numberOfLines = 0 if (mPin == nil ) { mPin = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: PINID) mPin?.canShowCallout = true } else{ mPin?.annotation = annotation } mPin?.leftCalloutAccessoryView = nil let btn = UIButton(type: .detailDisclosure) mPin?.rightCalloutAccessoryView = btn subtitleView.text! += String(i) subtitleView.text = "Total Load: " subtitleView.text! += String(detail.sales) subtitleView.text! += " \r\n" subtitleView.text! += "Total Target: " subtitleView.text! += String(detail.target) subtitleView.text! += " \r\n" i += 1 // } mPin!.detailCalloutAccessoryView = subtitleView mPins.append(mPin!) } return mPins } The marker pins show up, but then the label does not popup. How to fix this?
Posted
by vihrao.
Last updated
.