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

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
967
Oct ’23
"Failed to set up CloudKit integration" in TestFlight build
I'm building a macOS + iOS SwiftUI app using Xcode 14.1b3 on a Mac running macOS 13.b11. The app uses Core Data + CloudKit. With development builds, CloudKit integration works on the Mac app and the iOS app. Existing records are fetched from iCloud, and new records are uploaded to iCloud. Everybody's happy. With TestFlight builds, the iOS app has no problems. But CloudKit integration isn't working in the Mac app at all. No existing records are fetched, no new records are uploaded. In the Console, I see this message: error: CoreData+CloudKit: Failed to set up CloudKit integration for store: <NSSQLCore: 0x1324079e0> (URL: <local file url>) Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.cloudd was invalidated: failed at lookup with error 159 - Sandbox restriction." UserInfo={NSDebugDescription=The connection to service named com.apple.cloudd was invalidated: failed at lookup with error 159 - Sandbox restriction.} I thought it might be that I was missing the com.apple.security.network.client entitlement, but adding that didn't help. Any suggestions what I might be missing? (It's my first sandboxed Mac app, so it might be really obvious to anyone but me.)
2
0
2.2k
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
323
Oct ’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
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
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
372
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
How to deduplicate entities with relationships in NSPersistentCloudKitContainer?
In my app I have a defaultJournal: Journal, that automatically gets added on the user's device on launch. There should only be one "default" journal, and I know that deduplication as shown in the Apple Demo, is the correct approach to ensure this on multiple devices. Journal looks something like: class Journal: NSManagedObject { @NSManaged var isDefaultJournal: Bool @NSManaged var entries: Set<JournalEntry>? } Since Journal has a relationship to entries, how can I deduplicate it ensuring that I don't orphan or delete the entries? I am worried that the entries aren't guaranteed to be synced, when we discover a duplicate journal in processPersistentHistory. This would lead to either orphaned or deleted entries depending on the deletion rule. How can one handle deduplicating entities with relationships? For example here is my remove function:     func remove(duplicateDefaultCalendarNotes: [Journal], winner: Journal, on context: NSManagedObjectContext) {         duplicateDefaultCalendarNotes.forEach { journal in             defer { context.delete(journal) } // FIXME: What if all of the journal entries have not been synced yet from the cloud? // Should we fetch directly from CloudKit instead? (could still lead to orphaned/deleted journal that have not yet been uploaded)             guard let entries = journal.entries else { return }             entries.forEach {                 $0.journal = winner             }         }     } A missing tag on a post isn't that bad, but deleting a user's journal is unacceptable. What is the best strategy to handle this?
1
1
902
Sep ’23
SwiftData error: NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release
I am using SwiftData for my model. Until Xcode 15 beta 4 I did not have issues. Since beta 5 I am receiving the following red warning multiple times: 'NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release This seems to be a CoreData warning. However, I am not using CoreData directly. I have no way to change the config of CoreData as used by SwiftData. My model just uses UUID, Int, String, Double, some of them as optionals or Arrays. I only use one attribute (.unique).
4
1
1.6k
Sep ’23
Weird Coredata error
Hi I really don't understand. I have a record type on CloudKit where I store some data and a corresponding entity on core data that I sync with CloudKit with a very basic routine at some point I call this func: func GetUserFromCoredata(userID:String)->UserEntity? { var fetched:[UserEntity]?=nil let fetch = NSFetchRequest<UserEntity>(entityName:"UserEntity") let predicate = NSPredicate(format:"TRUEPREDICATE") fetch.predicate = predicate fetch.affectedStores = [DBGlobals.localStore, DBGlobals.cloudStore] do{ print("RICHIESTA FETCH UTENTI IN COREDATA") fetched = try context.fetch(fetch) } catch{ fatalError("errore nel recupero dell'elenco utenti") } if let found = fetched { for el in found { if el.userID == userID { return el } } } return nil } As you can see nothing special. it is only a fetch made on two stores. If I run the code 20 times 19 are good and 1 result in a fatal error with this text: 2023-06-28 17:56:49.684780+0200 xDeskApp[23313:2379150] -[__NSCFConstantString bytes]: unrecognized selector sent to instance 0x215632f50 2023-06-28 17:56:49.712724+0200 xDeskApp[23313:2379150] [error] error: SQLCore dispatchRequest: exception handling request: <NSSQLFetchRequestContext: 0x283d88000> , -[__NSCFConstantString bytes]: unrecognized selector sent to instance 0x215632f50 with userInfo of (null) 2023-06-28 17:56:49.974635+0200 xDeskApp[23313:2379150] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFConstantString bytes]: unrecognized selector sent to instance 0x215632f50' *** First throw call stack: (0x1bd4d4cb4 0x1b657c3d0 0x1bd649ab8 0x1bd4eb0e8 0x1bd551900 0x1c4c53594 0x1c4bdf848 0x1c4bdf4b0 0x1c4c81d80 0x1068fa038 0x10690b814 0x1c4c81c20 0x1c4bcef68 0x1c4bcee38 0x1c4bbe200 0x1c4bc9a78 0x1c4d3752c 0x1c4c02678 0x1c4bc86d8 0x1c4bbb9fc 0x1c4bb6b14 0x1c4cc97ec 0x104bf00b0 0x104bef860 0x104bee8f4 0x1c4f82ce8 0x1c4f82d8c 0x1c5068cac 0x1c4f1f3b0 0x1c4f11338 0x1c50689d4 0x1bd53dc04 0x1bd4ebcb4 0x1bd4eb6cc 0x1c4fcc800 0x10690b158 0x1068fa038 0x1069020b0 0x106902e28 0x10690fc74 0x21d250ddc 0x21d250b7c) libc++abi: terminating due to uncaught exception of type NSException (Recorded stack frame) ... and really, I can't understand. the predicate is absolutely basic, the entity exist, here I am not syncing anything, just fetching the records in the two stores... what am I doing wrong? why 19 su 20 are good and one is catching this error?
2
0
741
Sep ’23
[NSPersistentCloudKitContainer] CloudKit integration forbids renaming 'OldEntityName' to 'NewEntityName'. Older devices can't process the new records. How to proceed?
I used a renaming identifier to rename an Entity Name, but it doesn't seem to work and it causes a crash at start during in-place migration. How to rename an Entity Name when using NSPersistentCloudKitContainer? I get this exception at start: CloudKit integration forbids renaming 'OldEntityName' to 'NewEntityName'. Older devices can't process the new records. Unresolved error Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." App is not in production, need a way to rename 'OldEntityName' to 'NewEntityName'. How to achieve this?
1
1
709
Sep ’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
822
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
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
SwiftUI, FetchedResults, and uninitliazed?
I've got @Environment(\.managedObjectContext) var context private var home: Home private var predicate: NSPredicate @State var sortBy: SortDescriptor<Room> @FetchRequest private var rooms: FetchedResults<Room> init(home: Home) { self.home = home _sortBy = State(initialValue: SortDescriptor<Room>(\.name)) self.predicate = NSPredicate(format: "%K = %@", "home", self.home) _rooms = FetchRequest<Room>( sortDescriptors: [self.sortBy], predicate: self.predicate) } But it won't compile -- it says Variable 'self.rooms' used before being initialized. But... how?
2
0
388
Sep ’23
Accessing array field with SwiftData throws exception
With the following code: @Model final class Item { var data: [Data] init(data: [Data]) { self.data = data } } @Model final class Data { var contents: String init(contents: String) { self.contents = contents } } .. let data = Data(contents: "yo") let newItem = Item(timestamp: Date(), data: [data]) print(newItem.data) // <-- exception thrown here I get an exception on the print line when accessing the .data field: Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1f379a29c) Note that if I first save newItem to the context the exception is not thrown, i.e.: let data = Data(contents: "yo") let newItem = Item(timestamp: Date(), data: [data]) modelContext.insert(newItem) print(newItem.data) // <-- no exception Unfortunately the exception is cryptic so I can't tell what's wrong. Xcode version 15.0 beta 8 (15A5229m) macOS Sonoma beta 14.0 (23A5337a)
3
2
932
Sep ’23
Initial sync of watchOS app using Core Data and CloudKit
I have an existing iOS/watchOS app that uses a third-party database and WatchConnectivity. For various reasons I am migrating the app to use Core Data with CloudKit. I have everything working using NSPersistentCloudKitContainer. Sync between the iOS and watchOS app are working on my test devices when I start with an empty database. However, I need to import existing user's data when they first install this new version. Some users may have hundreds or thousands of records, but the total database size is under 1-2MB. Data migration/import is working on the iOS side, the Core Data entities are populated on first launch and uploaded to CloudKit (I see in the debug logs that a NSPersistentCloudKitContainer.Event export ends successfully). The problem is launching the watchOS app does not sync the data from CloudKit. I see a import started event but never see it end. I never see any Core Data entities appear on watchOS even after waiting several minutes and re-opening the Watch app multiple times. New entities or modifications made on either app are also not synced. Is the problem just too much data which causes the CloudKit sync to never finish? What are the best practice to populate a watchOS app with initial data from the parent iOS app and keep it in sync with CoreData/CloudKit?
3
1
780
Sep ’23
Update Watch Complication with CloudKit
I have an iPhone app the uses CloudKit for Core Data syncing. I also have a companion Apple Watch app that syncs to the same CloudKit records. The watch can be used without the iPhone app as well but they both independently sync to the same CloudKit database. This works reasonably well. As soon as either app is opened, the CloudKit will pull down the latest records. I'd like to add a watch complication that shows the state of the CloudKit records. I supported this by adding a Widget extension, embedded in my watch app. The Core Data database in the watch app is part of an app group, so the complication is able to query the same database. So far so good. I'm running into problems with the complication updating after remote records are changed from the iPhone. Here is what is happening: When records are changed on the iPhone, the data syncs to CloudKit but the watch app is not updated when in the background. This is noticed when you open the app and it takes a second for the view to show the new records. Since Core Data database on the watch is not being updated while in the background, the complication is not being updated at all. Part of my confusion is I assumed CloudKit was meant to make this more seamless with silent push notifications? I have the "Remote Notifications" capability enabled on my WatchApp. It seems that only works while the app is in the foreground though. This seems very limiting when you have a complication that depends on the Watch app's Core Data state. I have a few things to work around this with mixed success: "Wake" the watch app explicitly when records are changed on the iPhone app using WatchConnectivityManager. The hope is that by waking the watch app, it will sync with iCloud. This either isn't working or intermittenly works. It is also not clear to me that by activating the watch app, that it will trigger records to sync. I wish there were a way to ask Core Data to sync explicitly. Whenever the Apple watch app wakes in the last step, ask it to WidgetCenter to reload the widget. This process feels convoluted and seems to negate some of the the benefits of CloudKit to synchronize data which I thought would be baked into this process. Any thoughts on a better approach to all this?
3
1
1.3k
Sep ’23