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

Core Data error: 'cannot use an attribute type of "Composite"' when "Used with CloudKit" checked
Hello, I'm running into an odd error. I'm trying to add a composite attribute called period to a Core Data Entity named Report, but I'm getting a compile-time error that points to my xcdatamodel file: Report.period cannot use an attribute type of "Composite". In my model configuration I have "Used with CloudKit" box checked. If I uncheck this box, the error goes away and everything builds fine. But the documentation for NSCompositeAttributeDescription says: You may use composite attributes anywhere you use standard attributes, including lightweight migrations and CloudKit, through NSPersistentCloudKitContainer. So it seems like I should be able to use composite attributes in Core Data with CloudKit syncing enabled. What am I missing here? Is this a bug, or am I doing something wrong?
2
0
345
Oct ’23
Xcode 15: Core Data : No NSValueTransformer with class name *** was found for attribute YYY on entity ZZZ for custom `NSSecureUnarchiveFromDataTransformer`
Hi, I am creating a custom NSSecureUnarchiveFromDataTransformer in order to handle attributes of entities of type NSDateComponents. It all works and I did not see any warnings in the "Issue navigator" inside Xcode but with Xcode 15 I started seeing this warning: /Users/.../CustomNSSecureUnarchiveFromDataTransformer/CoreData:1:1 no NSValueTransformer with class name 'CustomSecureUnarchiveFromDataTransformer' was found for attribute 'testDate' on entity 'Item' My use case is very simple, I have this custom transformer: @objc(CustomSecureUnarchiveFromDataTransformer) final class CustomSecureUnarchiveFromDataTransformer: NSSecureUnarchiveFromDataTransformer { override class var allowedTopLevelClasses: [AnyClass] { return [NSDateComponents.self] } static let name = NSValueTransformerName(rawValue: String(describing: CustomSecureUnarchiveFromDataTransformer.self)) public static func register() { let transformer = CustomSecureUnarchiveFromDataTransformer() ValueTransformer.setValueTransformer(transformer, forName: name) } } which is set to the Core data entity's "Transformer": which leads to the warning in Xcode 15. App works just fine and there are no problems during run time, but this warning is shown and I want to fix it. Here is a simple test project https://github.com/VladimirAmiorkov/CustomNSSecureUnarchiveFromDataTransformer
12
10
2.6k
4w
new swift concurrency model with core data willSave()
anyone know how to use the new swift concurrency model (ie. await context.perform and context.perform) core data willSave()? for example. how would I ensure this is thread safe? changing self.managedObjectContext!.performAndWait to await self.managedObjectContext!.perform means I have to change willSave() to async which then means it never gets called because its not overriding the correct method anymore. override public func willSave() { self.managedObjectContext!.performAndWait { if self.modifiedDate == nil || Date().timeIntervalSince(self.modifiedDate!) >= 1 { self.modifiedDate = Date() } } super.willSave() }
0
0
578
Oct ’23
Designing a Word of the Day App: Balancing Local Word Data with Cloud-Based Learning Records"
I have a "Word of the Day" application with a CoreData database containing approximately 14,000 word entities. These entities have attributes like frequency (indicating how often a word appears in some corpus), definition, and pronunciation. Currently, this information is stored locally. I want to add a feature that allows users to store their learning data about these words. For example, users should be able to mark words with a rating of 1, 2, or 3 to indicate their degree of familiarity with the words. My ultimate goal is to display the highest-frequency word with a user familiarity rating of 1 and display it as todays word of the day. The challenge I'm facing is how to set up my app so that learning data is stored in the cloud while the word information remains stored locally. I've seen that you can create different configurations and have one connected to CloudKit, but this approach may make it difficult to write queries that combine information from both the Word entity and the LearningData entity. I'm looking for suggestions on how to address this issue effectively.
0
0
284
Oct ’23
In CloudKit, how do I check whether the user of an app is the share-sender or the share-receiver?
In other words, I’m trying to setup sharing in my app using Core Data with CloudKit. Basically the user can share their list of CloudKit records with other users of the app. Should that other user accept that share from that share-sender, the share-receiver can then sees the sender’s list of records. This part works as I need it to. This is fine. As well, the app is largely being written in SwiftUI. However, what I also need is to give the user the ability to see only their own records, or to set one of their records to private. I think I can figure this logic out, but I’m still not sure of how to filter the sender versus receiver of that share, AKA owner vs participant. I’ve tried several things to figure this out, and I keep coming up empty. I feel like there’s a good way to do this, however what I’ve done always has issues. Can someone please describe the best way to do this?
0
0
408
Oct ’23
Receiving NSPersistentStoreRemoteChange notification when app is closed
I use NSPersistentCloudKitContainer to fetch/sync data across multiple devices with the same iCloud account. /// ... container = NSPersistentCloudKitContainer(name: containerName) let description = container.persistentStoreDescriptions.first description?.setOption( true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) description?.setOption( true as NSNumber, forKey: NSPersistentHistoryTrackingKey) let viewContext = container.viewContext viewContext.automaticallyMergesChangesFromParent = true viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump NotificationCenter.default.addObserver( forName: .NSPersistentStoreRemoteChange, object: container.persistentStoreCoordinator, queue: .main ) { _ in Task { @MainActor [weak self] in // fetch new data and update widgets with it // ... viewContext.fetch ... // WidgetCenter.shared.reloadAllTimelines() } } } /// ... Everything works fine when my app in the foreground. How can I achieve the same when my app is closed/ in the background? I know that CloudKit can send silent push notification which can wake up my app but I've never seen the implementation of it using CoreData NSPersistentCloudKitContainer
0
0
429
Oct ’23
Swiftdata: CloudKit integration requires that all attributes be optional, or have a default value set
Unfortunately I can not get swiftdata to work for me. I created a brand new project in Xcode, modified no code and the program fails with this error. Only thing I did was add an iCloud container. The default code that you are given for a swiftadata object is: @Model final class Item { var timestamp: Date init(timestamp: Date) { self.timestamp = timestamp } } Xcode wants that values in this model to ether be optional or have a default value. I thought this was a bug that had been fixed, but I am on the latest Xcode. I am not sure how to proceed. If the default code Xcode gives you won't compile, how am I able to code my own?
1
0
527
Oct ’23
Core Data query for Transformable
Hi, in my Core Data model, I’m using Transformable to store values of different kinds to the same attribute (I’m creating a user generated filter for data, that could filter for Integers, Boolean or other values - to avoid creating attributes for each possible types i‘m using transformable Any). now, while querying for these values, I’ve noticed that this attribute is never correctly evaluated, but is always false. is it possible to query for Transformable or do I need to change my approach and create an attribute for each possible Type?
0
0
324
Oct ’23
App structure for iOS app, widgets, watchOS app & complications?
I've had to rewrite my app to get widgets working properly, and I've got this project structure: Main iOS app: Bundle identifier = com.me.myapp Contains: Widget Extension: Bundle identifier = com.me.myapp.widgets Targets iOS 17 Provides widgets to iOS Watch app: Bundle identifier = com.me.myapp.watchapp Contains: Complications Extension (a Widget Extension): Bundle identifier = com.me.myapp.watchapp.complications Targets watchOS 10 Provides widgets to watchOS On the Signing & Capabilities tab in Xcode 15, all four targets have: Provisioning Profile: Xcode Managed Profile Signing Certificate: Apple Development: My team App Groups: all use the same one: group.com.me.myapp I can build and deploy to a physical iPhone and Apple Watch, but the Watch app doesn't seem to be able to access the shared Core Data, which should be in the shared app group container. When running the main iOS app, the store location is: file:///private/var/mobile/Containers/Shared/AppGroup/189E5907-E6E4-4790-833F-06944E4FF5FF/data-model/TheDataModel When running the widget extension, the store location is: file:///private/var/mobile/Containers/Shared/AppGroup/189E5907-E6E4-4790-833F-06944E4FF5FF/data-model/TheDataModel When I run the Watch app, the store location is different: file:///private/var/mobile/Containers/Shared/AppGroup/55381E6D-410E-4322-93BA-64BD1933909E/data-model/TheDataModel How do I get the Watch app to see the Core Data store from the main app? Do I have to replicate the store to that location every time something changes in the main app? Or do I have to go back to sending massive data sets as dictionaries/data via WatchConnectivity?
1
0
968
Oct ’23
Access iOS app CoreData in Swift extension?
This should be simple, but it's proving immensely difficult and annoying. I have three targets in the project: an iOS app written in Objective-C a Watch App written in Swift/SwiftUI a Widget Extension with my widgets and complications in, written in Swift/SwiftUI I want to access the Core Data that's got all my app's data in it from the Widget Extension and Watch App. How do I do this? Every internet search result assumes all your targets are in Swift, and it's really not feasible for me to rewrite the entire app. All three targets have the same App Group set up, and I can access UserDefaults in each target. I have a CoreData.swift class in a shared folder, and it's a member of both the Watch App and Widget Extension targets. It has this in it: lazy var persistentContainer: NSPersistentContainer = { let storeURL = URL.storeURL(for: kAppGroup, databaseName: kCoreDataModel) let storeDescription = NSPersistentStoreDescription(url: storeURL) let container = NSPersistentContainer(name: kCoreDataModel) container.persistentStoreDescriptions = [storeDescription] container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { fatalError("CoreData: Failed to initialise Managed Object Model from url: \(storeURL), with error: \(error), \(error.userInfo)") } }) return container }() and the storeURL extension is: public extension URL { static func storeURL(for appGroup: String, databaseName: String) -> URL { guard let fileContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup) else { fatalError("CoreData: Shared file container could not be created.") } return fileContainer.appendingPathComponent("\(kCoreDataModel).sqlite") } } To be clear, the main iOS app (in Objective-C) has created the Core Data model etc., and it all works fine. I just want to be able to access the data in that model from the other targets. (I only need read access.) When I deploy to a device the stack looks like this: NSURL *dataModelFolderURL = [[[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:kAppGroup] URLByAppendingPathComponent:kCoreDataFolder]; Is: /private/var/mobile/Containers/Shared/AppGroup/9F329A90-C897-4AA2-87DF-D98A9E85356A/data-model NSURL *modelURL = [[NSBundle mainBundle] URLForResource:kCoreDataModel withExtension:@"momd"]; Is: file:///private/var/containers/Bundle/Application/CA9E3697-C4C6-48CB-89EA-CC441A6F81AF/MyApp.app/TheDataModel.momd/ // Wait until we have the store, or fetches will sometimes return no data [self performSelectorOnMainThread:@selector(getStore) withObject:nil waitUntilDone:YES]; storeURL = file:///private/var/mobile/Containers/Shared/AppGroup/9F329A90-C897-4AA2-87DF-D98A9E85356A/data-model/TheDataModel I've tried getting the Swift targets to look in a bunch of different paths, but nothing works. When I try to get a count of objects in the Core Data I always get zero results. The second of those outputs is from the bundle. I guess that's because the data model is held within the iOS app's structure? Does that make any difference? Should it be held somewhere else? If so, what should it be? (Minor rant: There really should be an option in Xcode that says, "This core data is shared here, here and here, and all you need to do is type CoreData.getSomeData() and you're done", but no, we have to write boilerplate code for everything.) Anyway... any help is appreciated.
1
0
597
Oct ’23
Core Data: Merging relevant changes between extensions and iCloud devices
I am working on an interactive widget and merging changes provided by a user over it with the app. I store my data, using Core Data. However, I noticed an issue with sync between other user's devices after that person made a change over the widget (in my case, it is completing a task). Here is my schema: Main app: it looks for relevant transactions (https://developer.apple.com/documentation/coredata/consuming_relevant_store_changes). When it found that one, the app merges changes: if transaction.author == "widget" { if let userInfo = transaction.objectIDNotification().userInfo { NSManagedObjectContext.mergeChanges(fromRemoteContextSave: userInfo, into: [taskContext]) } } Widget: If the user clicks on the checkbox in order to complete a task, using an AppIntent class, app creates an identical NSPersistentCloudKitContainer and completes the task. However, in that case, the NSPersistentCloudKitContainer of the widget does not look for changes. That works correctly. However, only in a local environment. Here's why: If I complete a task (using a widget) and launch the app on the same device, the change will be synced correctly. If I complete a task (using a widget) (on device A) and launch the app on another device (on device B), the change will not be applied (on device B), until I open the app on the device that I made the change on (on device A). If I open the app on device B after I opened it on device A (and the changed has been applied), on device A I get a remote notification with the author value = 'NSCloudKitMirroringDelegate.import', not 'widget'. The point of my issue is that the remote notifications about changes made, using widgets, does not arrive to other devices like notifications initialised by the main app. Thank you in advance!
1
1
585
Nov ’23
CloudKit stopped syncing on WatchOS
Hey, I have an iOS/watchOS application that has been in the App Store since the beginning of last year (for reference: https://endsplus.com). Part of the functionality includes: Create a Fixture on the Phone Create Fixture on iOs Fixture is saved to Core Data Core Data syncs with CloudKit WatchOs pulls down the record, updating a table of the same name I can show the Fixtures on the Watch. Track a game on the Watch and then save it. Create a Game on WatchOS Game is saved to Core Data Core Data syncs with CloudKit iOS pulls down the record, updating a table of the same name I can show the games on the phone. For reasons I am unable to work out syncing of core data tables between the phone and the watch has stopped working. I know that the iOS coredata/cloudkit functionality is working as I can create a record on my physical phone, then run a simulator and log in with the same iCloud account and see the record. But the functionality has stopped working for watchOS. I have added a new table to the Watch side that is not syncing to the Phone, but an existing table (Fixture) that has been working has also stopped syncing between the phone and the watch. None of my Persistence/Core Data code has changed. My new table is associated with a Cloud Store, the same as my old table is. What options are they available to me to try and debug this. The watchOs simulator doesn't seem to work with CloudKit, telling me it is not signed in. I've tried looking at the CloudKit database logs, but obviously for security I can't see the data, but I can't see any errors from the watch. I've uninstalled and re-installed the application (on the phone and the watch) numerous times, but that isn't working. Does anyone have any ideas? Thanks
4
0
667
Oct ’23
NSPersistentStoreCoordinator crash (routeHeavyweightBlock?)
Hello, I recently published an app on the App Store. I see a crash log from one of my users, but don't understand the reason CoreData crashed. It was simply saving a single object, and all the properties of it are optional. I am unable to reproduce the crash, and in the over 8 moths of development before release, I did not encounter this type of error. Please provide assistance, or where I could do some more research. I included part of the crash log below. Thank you very much. Hardware Model: iPhone15,4 Process: Proaneer Version: 1.0.3 (50) AppStoreTools: 15A240a AppVariant: 1:iPhone15,4:17 Code Type: ARM-64 (Native) Role: Foreground Parent Process: launchd [1] Date/Time: 2023-10-01 09:14:05.6888 -0400 Launch Time: 2023-10-01 09:08:34.4421 -0400 OS Version: iPhone OS 17.0.2 (21A350) Release Type: User Baseband Version: 1.00.03 Report Version: 104 Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x0000000000000000, 0x0000000000000000 Termination Reason: SIGNAL 6 Abort trap: 6 Terminating Process: Proaneer Triggered by Thread: 0 Last Exception Backtrace: 0 CoreFoundation 0x19a4565e0 __exceptionPreprocess + 164 (NSException.m:249) 1 libobjc.A.dylib 0x192767c00 objc_exception_throw + 60 (objc-exception.mm:356) 2 CoreData 0x1a2609410 -[NSPersistentStoreCoordinator _introspectLastErrorAndThrow] + 120 (NSPersistentStoreCoordinator.m:0) 3 CoreData 0x1a24f3fbc __65-[NSPersistentStoreCoordinator executeRequest:withContext:error:]_block_invoke.541 + 680 (NSPersistentStoreCoordinator.m:0) 4 CoreData 0x1a24f3c2c -[NSPersistentStoreCoordinator _routeHeavyweightBlock:] + 264 (NSPersistentStoreCoordinator.m:641) 5 CoreData 0x1a24d05b4 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 1048 (NSPersistentStoreCoordinator.m:2768) 6 CoreData 0x1a24d05d8 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 1084 (NSPersistentStoreCoordinator.m:3425) 7 CoreData 0x1a24c1e84 -[NSManagedObjectContext save:] + 972 (NSManagedObjectContext.m:1625) 8 Proaneer 0x102f2e268 ContactListViewModel.saveContact(functionName:functionAction:count:) + 96 (ContactListViewModel + CRUD Ext..swift:151) 9 Proaneer 0x102f2e1e4 ContactListViewModel.createContact() + 2496 (ContactListViewModel + CRUD Ext..swift:50) 10 Proaneer 0x102f7e08c closure #1 in closure #1 in closure #2 in closure #1 in closure #5 in ContactListRootView.body.getter + 84 (ContactListRootView.swift:203)
1
1
373
Oct ’23
Saving to Core Data during device locking & unlocking
The following error message "SIGABRT: This NSPersistentStoreCoordinator has no persistent stores (device locked). It cannot perform a save operation" has indicated need to provide for sequencing of the Core Data context saving operation. We want to avoid .save() if locking is in flight, also postpone .save() until unlocking has completed. Currently our .save() is bracket by do-catch block but this is notably not helping in the case of SIGABR signal Given that our saving operations must take place synchronously, what is the recommended practice to implement such sequencing with respect to locking / unlocking
0
0
322
Sep ’23
Fetch recurring objects using CoreData predicate
Hello! I was wondering if there's any open source example how to implement SUBQUERY in CoreData in calendar based app? For example: User creates an event with subtasks on the 1st on September with daily frequency On the 5th of September they update just that day event's details, some subtasks. On the 7th of September they see the same event that was created on the 1st of September. Structs that can describe the case may look like this: enum Frequency { case daily case weekly case monthly } struct Subtask { var name: String var isCompleted: Bool } struct Event { var id: UUID var name: String var startAt: Date var repeatUntil: Date? var isCompleted: Bool var subtasks: [Subtask] var frequency: Frequency? var excludedOn: [Date] } For each day on a week I need to fetch events from CoreData, so I'm wondering how predicate can look like in such case? I met SUBQUERY, but I'm not sure how to apply weekly and monthly frequency frequency into NSPredicate (for daily it's pretty straightforward). Would be glad for any advices! ~Paul
0
0
285
Sep ’23
watchOS 10: CloudKit CoreData Sync (NSPersistentCloudKitContainer) Requires Watch on Charger
I've encountered a significant sync issue with watchOS 10 RC on every device combination I've tested, running both iOS 17 and watchOS 10. I'm curious if others have noticed a similar problem. Context: Standalone watchOS app developed in SwiftUI with a companion iOS app. Both apps use NSPersistentCloudKitContainer for bi-directional CloudKit CoreData Sync between the iOS app and watch. Previously, this sync mechanism was near instant in the foreground and took max 1-2 minutes in the background NSPersistentCloudKitContainer has been reliable since the app was first developed in the watchOS 6/iOS 13 era. Issue: In watchOS 10 RC, sync can take hours--and doesn't even occur when the app is in the foreground. Sync only reliably happens when the watch is placed on the charger, seemingly only if the charge is over 50%. Once taken off the charger, the watch will continue push and receive CoreData changes briefly before becoming unresponsive to sync again. Additional Info: The problem persists even when recompiled with the latest Xcode RC. It's problem is consistent in both production and development CloudKit environments. The CloudKit log shows no watch activity upon CoreData object updates, until placed on the charger (with over 50% charge). The sync starts in the background while the watch is charging. The iOS app, however, reflects immediate activity in the CloudKit log after a CoreData change from the device and reacts promptly to pushes when they eventually occur from the watch. The NSPersistentCloudKitContainer code hasn't changed since it was implemented. Background modes for remote notifications are set correctly, and when sync finally happens, it's accurate. I'm stumped. Perhaps there's a new watchOS 10 setting affecting CloudKit sync QoS? Or could this be a known watchOS 10 RC bug?
12
6
1.7k
Nov ’23
Group Core Data items by category in List in SwiftUI
I have a Core Data container with two entities, a Category and an Item. The Item can have one Category assigned and the Category can be assigned to many Items. What I need to do is group the items by category in a list in SwiftUI. The code below doesn't group all items by category, it only shows one item by category. How can I group all items that have the same category assigned under the same category group? Core Data Entities Category Attributes name Relationship items (Type: To Many) Item Attributes name Relationship category (Type: To One) Swiftui struct ItemsView: View { let selectedList:List @EnvironmentObject private var itemSM: ItemServiceModel var body: some View { List { ForEach(itemSM.items) { item in Section(header: Text(item.category?.name ?? "")) { ForEach(itemSM.items.filter { $0.category == item.category }) { filteredItem in Text("\(filteredItem.name ?? "")") } } } } .onAppear{ itemSM.loadItems(forList: selectedList) } } } Service Item Service Model class ItemServiceModel: ObservableObject{ let manager: CoreDataManager @Published var items: [Item] = [] func loadItems(forList list: List){ let request = NSFetchRequest<Item>(entityName: "Item") let sort = NSSortDescriptor(keyPath: \Item.name, ascending: true) request.sortDescriptors = [sort] let filter = NSPredicate(format: "list == %@", list) request.predicate = filter do{ items = try manager.context.fetch(request) }catch let error{ print("Error fetching items. \(error.localizedDescription)") } } } This is what I see, as you can see, only one Fruits & Vegetables section should exist.
4
0
823
Sep ’23
How to check if data is fetched from CloudKit?
When using CloudKit in an app, if there are data changes on other devices being synchronized, and you also want to make changes to the data on the current device and reflect it back to the CloudKit server, you might want to display a native loading icon, like the one you see in the Notes app, during this process. How can you implement this? If anyone knows how to do it using SwiftUI, please let me know.
0
0
290
Sep ’23