Search results for

“NSPersistentCloudKitContainer”

601 results found

Post

Replies

Boosts

Views

Activity

Reply to NSPersistentCloudKitContainer losing data
1. Are you suggesting that iCloud-sync should be enabled by default and if the users want to turn it off then they can do that from System Settings app? Yeah, that will be my choice. 2. Based on your answer, I think I agree that having toggle to enable/disable iCloud will not provide consistent experience. But then I don't understand how that can be fixed since iCloud is available only to the premium users in the app. The toggle is off and disabled for the free users of the app. I didn't think that you'd build your business model based on that. Thanks for bringing this up. I haven't thought from the business model perspective, but one idea is to consider creating a local store and a CloudKit store to manage the data separately. When users choose to opt in, you move the data from local store to the CloudKit one, and let NSPersistentCloudKitContainer take care the rest. By using a local store, you control when to move what data to the CloudKit store. For details about managing multiple stores with one
Sep ’24
Reply to preload core data from cloud kit
This what I use in my apps (during the initialisation of my Data Controller): self.mainContainer = { let container = NSPersistentCloudKitContainer(name: MyDataModel) container.loadPersistentStores(completionHandler: { description, error in if let error = error { print(**** ERROR loading persistent store (error)) } //Setup auto merge of Cloudkit data container.viewContext.automaticallyMergesChangesFromParent = true container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy //Set the Query generation to .current. for dynamically updating views from Cloudkit try? container.viewContext.setQueryGenerationFrom(.current) }) return container }() The key lines are the 2 below //Setup auto merge. Also, be sure to have enabled Remote Notifications in Background modes of the App's Signing and Capabilities. I hope this helps. Regards, Michaela
Apr ’23
Reply to Error while trying to save two records with CKReference to each other
Ok I've narrowed the issue down. If my call to setParent on the Chat object (line 13 above of the first code listing). If I remove this line. Everything works and my two references are saved so each record has a reference to each other. However I believe then that I'm missing the benefits of using setParent? So that when I do an update to a child object things are kept in sync? Or is setParent only to be used when using CoreData/CloudKit syncing that was introduced in 2019 with NSPersistentCloudKitContainer? I'm not using that (as much as I'd like to) because I need to share my records. So I'm doing the Core Data/Cloud Kit syncing myself.
Jul ’20
Reply to NSMigrationManager.migrateStore with NSPersistentHistoryTrackingKey
How can I confirm this behavior when migrating using NSMigrationManager? I don't think you need to explicitly checkpoint the store. The Core Data migration process should handle that for you – If it doesn't, I'd see that a framework bug When I enable com.apple.CoreData.MigrationDebug the lightweight migration logs the WAL checkpointing, however, when using NSMigrationManager no such log appears. When I tried inserting 1000 objects, all of them get inserted into the sqlite file. Nothing gets inserted in WAL file. Is the behavior different for NSPersistentCloudKitContainer? Regarding the error, did you try to set up options in the following way: Yes, this works. However, if the NSMigrationManager handles this then should be avoided, right?
Feb ’25
Reply to WidgetKit and CoreData/CloudKit
I don’t think this last comment is accurate, at least as of iOS 15. In digital lounges at WWDC Apple engineers explained it is possible for NSPersistentCloudKitContainer to sync while your app is open in the background. It seems though the work is scheduled with utility priority. In my testing it will sync if you make 4 changes - once enough updates are accumulated it’ll process them. But even then my widget is showing the changes from the 3rd update because it hasn’t yet finished updating it seems, and attempting to delay it causes the code not to execute I assume because iOS suspends the app again very soon after. So basically it may eventually sync in background, only if your app is already open in background, and it may not be reliable and your widget might not get the most up-to-date data. Maybe this can be improved by utilizing background task API, that’s what they suggested trying in the digital lounge. Do note they also said NSPersistentCloudKitContainer does not support multi-proces
Jun ’22
Reply to Strange behavior with 100k+ records in NSPersistentCloudKitContainer
I’m having a similar problem. I found a reddit post about this issue where the author writes, “I’m guessing it only shows up for devs who bulk import/delete during testing, while normal users with a few hundred records never notice.” Which makes sense because I am also bulk importing. I’m seeing about a 6-8 times increase between the local storage and CloudKit. (Specifically, 15k records comes out to around 13mb of local storage, but 100mb with CloudKit enabled. ANSCKRECORDMETADATA appears to be the main culprit.) I’m making a flashcard app, and of course users can import as many cards as they want, which could become a storage problem pretty quickly. From my understanding, and as you mentioned, a storage increase is expected. But the increase I’m seeing just seems excessive. … Or is it? I can’t really find anything on what to expect. I wonder if there’s something I can change in the model to make this work. Or maybe the problem is unique to NSPersistentCloudKitContainer and I should look at other sy
Nov ’25
Reply to Siri Shortcuts with SwiftUI and Core Data
Short Answer: It is a bug. Just run (command + R) your app then stop it. Then talk to your Siri. You will see the new Item is added to your list. I think debugger stops core data to be updated from external events. Long Answer: I also tried many different approaches in the web and nothing worked. But here is the simplest code that I could add item to my list via Siri. Simply setup your PersistenceController public struct PersistenceController { public static let shared = PersistenceController() public let container: NSPersistentCloudKitContainer init(inMemory: Bool = false) { container = NSPersistentCloudKitContainer(name: YourApp.) if inMemory { container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: /dev/null) } else { let storeURL = AppGroup.coredata.containerURL.appendingPathComponent(YourApp.sqlite) let description = NSPersistentStoreDescription(url: storeURL) container.persistentStoreDescriptions = [description] } container.loadPersistentStores(completionHandler: { (sto
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’22
Reply to Persisting User Settings with SwiftData
I'd like to comment the second question a bit, as it hasn't been addressed yet: Sometimes when running on a new device it will create a second UserSettings while it is waiting for the original one to sync from CloudKit. When you use SwiftData + CloudKit, under the hood, the framework uses NSPersistentCloudKitContainer to synchronize data. In that environment, duplicate data is sometimes inevitable, which is discussed in great details in the following section: Remove duplicate data The solution is to de-duplicate the data. How to do so is discussed and demonstrated in the sample code. Back to what to what you intent to achieve, my suggestion will be: If you plan to use SwiftData + CloudKit extensively in your app, you might need to handle duplicate data anyway. In this case, persisting user settings to your SwiftData store (and Synchronizing them via NSPersistentCloudKitContainer) makes a lot of sense. If the target is as simple as saving some Cloud-based user settings, I'd probably consider
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jan ’26
Reply to Widget error upon restore iPhone: The file "Name.sqlite" couldn't be opened
I'm sorry, I thought I'd already replied to this... destroyPersistentStore isn't the right API that deletes the data lol Can you clarify what you mean by destroy those CoreData objects? What I mean by destroy here is get rid of your reference to the read/write NSPersistentCloudKitContainer object. That will then: Free up some memory (minor benefit). Ensure that you can't accidentally get a read/write object reference, since your app won't have a reference to the object that COULD have given you one. (major benefit). In code level terms, this would mean either NULL out a var reference or having the let go out of scope. __ Kevin Elliott DTS Engineer, CoreOS/Hardware
Jun ’25
Reply to CoreData+CloudKit w/ Large Public Database
Assume the public database contains 10,000+ Locations from which a User would select a few as favorites How large are these locations? For example 10k CLLocation objects is a trivially small dataset for CoreData to manage. It could be downloaded in seconds or minutes and queried extremely efficiently in local storage with indexed fields or via Spotlight. Sending out a CKQueryOperation for each search requires network and unnecessarily drains a customers battery. NSPersistentCloudKitContainer supports millions of records as long as they fit in local storage. Another approach is to simply ship the locations with your application in a CoreData store that's part of your application bundle and added as a read-only store to the container.
Jan ’24
Reply to CloudKit and CoreData synchronization
hi, it may be as simple as not turning on history tracking. in my code, i usually have these lines right after creating the NSPersistentCloudKitContainer: // (1) Enable history tracking. this seems to be important when you have more than one persistent // store in your app (e.g., when using the cloud) and you want to do any sort of cross-store // syncing. See WWDC 2019 Session 209, Making Apps with Core Data. guard let persistentStoreDescription = container.persistentStoreDescriptions.first else { fatalError((#function): Failed to retrieve a persistent store description.) } persistentStoreDescription .setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) persistentStoreDescription .setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) hope that helps, DMG
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’21
Reply to 0xdead10cc & NSPersistentCloudKitContainer
HI, Asking for more background time doesn't feel like a solution, that will just postpone the crash. Actually, that is the answer, at least partly. The reason this can't really happen: In my naiveté I assumed that NSPersistentCloudKitContainer and Core Spotlight would release any locks when app is suspended. ...is that the system can't really know in advance what you're going to ask it to do. They actually take out some of their own tasks, but that doesn't really help if the suspension process is starting at roughly the same time you're asking them to do work. That solution here is to create your own background task for the larger job that you're trying to finish (Add some stuff to my CoreSpotlight index) and end it once the work is done. -Kevin Elliott DTS Engineer, CoreOS/Hardware
Oct ’22
Reply to No persistent stores error in SwiftData
The crash you’re seeing— FAULT: NSInternalInconsistencyException: This NSPersistentStoreCoordinator has no persistent stores (unknown). It cannot perform a save operation. (Apple Developer) —happens because by the time your onAppear runs, the debug block has already loaded and then removed the only store from the underlying NSPersistentCloudKitContainer. When you immediately call newContainer = try ModelContainer(for: Page.self, configurations: config) SwiftData’s internal coordinator finds no stores to save into and throws. The fix is to perform both the CloudKit‐schema initialization and your ModelContainer setup early, in your App struct (or in its init), rather than inside an onAppear. That way SwiftData creates its SQLite store after you’ve torn down the temporary CloudKit container, so it can recreate a fresh store. For example: @main struct MyApp: App { // 1) Build your debug store, initializeCloudKitSchema, remove it… // 2) Then immediately create the SwiftData ModelContainer private var mode
May ’25
Reply to NSPersistentCloudKitContainer - Import failed because applying the accumulated changes hit an unhandled exception
Please file a bug report with Apple using Feedback, if you haven't already done so. Quote my report FB9859660. I am in the same situation as you, and feel as though I'm the only one! I too don't know what to say to my users, other than Apple have a bug and they are working on it, with no timescale for resolution. People are not happy! It was working perfectly well in iOS14. Now it's not in iOS15. Instruments suggests to me that there is probably a memory leak in NSPersistentCloudKitContainer. Large spikes in Virtual Memory usage on all imports (even the small ones) but the small ones dont trigger a crash. The same (smallish) database in iOS14 uses 36MB of VM but in iOS15 uses 1.49GB for example!!
Mar ’22
Reply to WidgetKit and CoreData/CloudKit
I might have answered my own question. First, add a managedObject variable to the TimelineProvider and a initializer: struct Provider: IntentTimelineProvider { var managedObjectContext : NSManagedObjectContext init(context : NSManagedObjectContext) { self.managedObjectContext = context } ... Then initialize the persistentContainer within the Widget struct and pass the persistentContainer.viewContext into the new Provider initializer: struct Widget_Extension: Widget { private let kind: String = Widget_Extension public var body: some WidgetConfiguration { IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider(context: persistentContainer.viewContext), placeholder: PlaceholderView()) { entry in Widget_ExtensionEntryView(entry: entry) } .configurationDisplayName(My Widget) .description(This is an example widget.) } var persistentContainer: NSPersistentCloudKitContainer = {... return container }() The Provider now has access to your CoreData+CloudKit data.
Jun ’20
Reply to NSPersistentCloudKitContainer losing data
1. Are you suggesting that iCloud-sync should be enabled by default and if the users want to turn it off then they can do that from System Settings app? Yeah, that will be my choice. 2. Based on your answer, I think I agree that having toggle to enable/disable iCloud will not provide consistent experience. But then I don't understand how that can be fixed since iCloud is available only to the premium users in the app. The toggle is off and disabled for the free users of the app. I didn't think that you'd build your business model based on that. Thanks for bringing this up. I haven't thought from the business model perspective, but one idea is to consider creating a local store and a CloudKit store to manage the data separately. When users choose to opt in, you move the data from local store to the CloudKit one, and let NSPersistentCloudKitContainer take care the rest. By using a local store, you control when to move what data to the CloudKit store. For details about managing multiple stores with one
Replies
Boosts
Views
Activity
Sep ’24
Reply to preload core data from cloud kit
This what I use in my apps (during the initialisation of my Data Controller): self.mainContainer = { let container = NSPersistentCloudKitContainer(name: MyDataModel) container.loadPersistentStores(completionHandler: { description, error in if let error = error { print(**** ERROR loading persistent store (error)) } //Setup auto merge of Cloudkit data container.viewContext.automaticallyMergesChangesFromParent = true container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy //Set the Query generation to .current. for dynamically updating views from Cloudkit try? container.viewContext.setQueryGenerationFrom(.current) }) return container }() The key lines are the 2 below //Setup auto merge. Also, be sure to have enabled Remote Notifications in Background modes of the App's Signing and Capabilities. I hope this helps. Regards, Michaela
Replies
Boosts
Views
Activity
Apr ’23
Reply to Error while trying to save two records with CKReference to each other
Ok I've narrowed the issue down. If my call to setParent on the Chat object (line 13 above of the first code listing). If I remove this line. Everything works and my two references are saved so each record has a reference to each other. However I believe then that I'm missing the benefits of using setParent? So that when I do an update to a child object things are kept in sync? Or is setParent only to be used when using CoreData/CloudKit syncing that was introduced in 2019 with NSPersistentCloudKitContainer? I'm not using that (as much as I'd like to) because I need to share my records. So I'm doing the Core Data/Cloud Kit syncing myself.
Replies
Boosts
Views
Activity
Jul ’20
Reply to NSMigrationManager.migrateStore with NSPersistentHistoryTrackingKey
How can I confirm this behavior when migrating using NSMigrationManager? I don't think you need to explicitly checkpoint the store. The Core Data migration process should handle that for you – If it doesn't, I'd see that a framework bug When I enable com.apple.CoreData.MigrationDebug the lightweight migration logs the WAL checkpointing, however, when using NSMigrationManager no such log appears. When I tried inserting 1000 objects, all of them get inserted into the sqlite file. Nothing gets inserted in WAL file. Is the behavior different for NSPersistentCloudKitContainer? Regarding the error, did you try to set up options in the following way: Yes, this works. However, if the NSMigrationManager handles this then should be avoided, right?
Replies
Boosts
Views
Activity
Feb ’25
Reply to WidgetKit and CoreData/CloudKit
I don’t think this last comment is accurate, at least as of iOS 15. In digital lounges at WWDC Apple engineers explained it is possible for NSPersistentCloudKitContainer to sync while your app is open in the background. It seems though the work is scheduled with utility priority. In my testing it will sync if you make 4 changes - once enough updates are accumulated it’ll process them. But even then my widget is showing the changes from the 3rd update because it hasn’t yet finished updating it seems, and attempting to delay it causes the code not to execute I assume because iOS suspends the app again very soon after. So basically it may eventually sync in background, only if your app is already open in background, and it may not be reliable and your widget might not get the most up-to-date data. Maybe this can be improved by utilizing background task API, that’s what they suggested trying in the digital lounge. Do note they also said NSPersistentCloudKitContainer does not support multi-proces
Replies
Boosts
Views
Activity
Jun ’22
Reply to Strange behavior with 100k+ records in NSPersistentCloudKitContainer
I’m having a similar problem. I found a reddit post about this issue where the author writes, “I’m guessing it only shows up for devs who bulk import/delete during testing, while normal users with a few hundred records never notice.” Which makes sense because I am also bulk importing. I’m seeing about a 6-8 times increase between the local storage and CloudKit. (Specifically, 15k records comes out to around 13mb of local storage, but 100mb with CloudKit enabled. ANSCKRECORDMETADATA appears to be the main culprit.) I’m making a flashcard app, and of course users can import as many cards as they want, which could become a storage problem pretty quickly. From my understanding, and as you mentioned, a storage increase is expected. But the increase I’m seeing just seems excessive. … Or is it? I can’t really find anything on what to expect. I wonder if there’s something I can change in the model to make this work. Or maybe the problem is unique to NSPersistentCloudKitContainer and I should look at other sy
Replies
Boosts
Views
Activity
Nov ’25
Reply to Siri Shortcuts with SwiftUI and Core Data
Short Answer: It is a bug. Just run (command + R) your app then stop it. Then talk to your Siri. You will see the new Item is added to your list. I think debugger stops core data to be updated from external events. Long Answer: I also tried many different approaches in the web and nothing worked. But here is the simplest code that I could add item to my list via Siri. Simply setup your PersistenceController public struct PersistenceController { public static let shared = PersistenceController() public let container: NSPersistentCloudKitContainer init(inMemory: Bool = false) { container = NSPersistentCloudKitContainer(name: YourApp.) if inMemory { container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: /dev/null) } else { let storeURL = AppGroup.coredata.containerURL.appendingPathComponent(YourApp.sqlite) let description = NSPersistentStoreDescription(url: storeURL) container.persistentStoreDescriptions = [description] } container.loadPersistentStores(completionHandler: { (sto
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jan ’22
Reply to Persisting User Settings with SwiftData
I'd like to comment the second question a bit, as it hasn't been addressed yet: Sometimes when running on a new device it will create a second UserSettings while it is waiting for the original one to sync from CloudKit. When you use SwiftData + CloudKit, under the hood, the framework uses NSPersistentCloudKitContainer to synchronize data. In that environment, duplicate data is sometimes inevitable, which is discussed in great details in the following section: Remove duplicate data The solution is to de-duplicate the data. How to do so is discussed and demonstrated in the sample code. Back to what to what you intent to achieve, my suggestion will be: If you plan to use SwiftData + CloudKit extensively in your app, you might need to handle duplicate data anyway. In this case, persisting user settings to your SwiftData store (and Synchronizing them via NSPersistentCloudKitContainer) makes a lot of sense. If the target is as simple as saving some Cloud-based user settings, I'd probably consider
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jan ’26
Reply to Widget error upon restore iPhone: The file "Name.sqlite" couldn't be opened
I'm sorry, I thought I'd already replied to this... destroyPersistentStore isn't the right API that deletes the data lol Can you clarify what you mean by destroy those CoreData objects? What I mean by destroy here is get rid of your reference to the read/write NSPersistentCloudKitContainer object. That will then: Free up some memory (minor benefit). Ensure that you can't accidentally get a read/write object reference, since your app won't have a reference to the object that COULD have given you one. (major benefit). In code level terms, this would mean either NULL out a var reference or having the let go out of scope. __ Kevin Elliott DTS Engineer, CoreOS/Hardware
Replies
Boosts
Views
Activity
Jun ’25
Reply to CoreData+CloudKit w/ Large Public Database
Assume the public database contains 10,000+ Locations from which a User would select a few as favorites How large are these locations? For example 10k CLLocation objects is a trivially small dataset for CoreData to manage. It could be downloaded in seconds or minutes and queried extremely efficiently in local storage with indexed fields or via Spotlight. Sending out a CKQueryOperation for each search requires network and unnecessarily drains a customers battery. NSPersistentCloudKitContainer supports millions of records as long as they fit in local storage. Another approach is to simply ship the locations with your application in a CoreData store that's part of your application bundle and added as a read-only store to the container.
Replies
Boosts
Views
Activity
Jan ’24
Reply to CloudKit and CoreData synchronization
hi, it may be as simple as not turning on history tracking. in my code, i usually have these lines right after creating the NSPersistentCloudKitContainer: // (1) Enable history tracking. this seems to be important when you have more than one persistent // store in your app (e.g., when using the cloud) and you want to do any sort of cross-store // syncing. See WWDC 2019 Session 209, Making Apps with Core Data. guard let persistentStoreDescription = container.persistentStoreDescriptions.first else { fatalError((#function): Failed to retrieve a persistent store description.) } persistentStoreDescription .setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) persistentStoreDescription .setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) hope that helps, DMG
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to 0xdead10cc & NSPersistentCloudKitContainer
HI, Asking for more background time doesn't feel like a solution, that will just postpone the crash. Actually, that is the answer, at least partly. The reason this can't really happen: In my naiveté I assumed that NSPersistentCloudKitContainer and Core Spotlight would release any locks when app is suspended. ...is that the system can't really know in advance what you're going to ask it to do. They actually take out some of their own tasks, but that doesn't really help if the suspension process is starting at roughly the same time you're asking them to do work. That solution here is to create your own background task for the larger job that you're trying to finish (Add some stuff to my CoreSpotlight index) and end it once the work is done. -Kevin Elliott DTS Engineer, CoreOS/Hardware
Replies
Boosts
Views
Activity
Oct ’22
Reply to No persistent stores error in SwiftData
The crash you’re seeing— FAULT: NSInternalInconsistencyException: This NSPersistentStoreCoordinator has no persistent stores (unknown). It cannot perform a save operation. (Apple Developer) —happens because by the time your onAppear runs, the debug block has already loaded and then removed the only store from the underlying NSPersistentCloudKitContainer. When you immediately call newContainer = try ModelContainer(for: Page.self, configurations: config) SwiftData’s internal coordinator finds no stores to save into and throws. The fix is to perform both the CloudKit‐schema initialization and your ModelContainer setup early, in your App struct (or in its init), rather than inside an onAppear. That way SwiftData creates its SQLite store after you’ve torn down the temporary CloudKit container, so it can recreate a fresh store. For example: @main struct MyApp: App { // 1) Build your debug store, initializeCloudKitSchema, remove it… // 2) Then immediately create the SwiftData ModelContainer private var mode
Replies
Boosts
Views
Activity
May ’25
Reply to NSPersistentCloudKitContainer - Import failed because applying the accumulated changes hit an unhandled exception
Please file a bug report with Apple using Feedback, if you haven't already done so. Quote my report FB9859660. I am in the same situation as you, and feel as though I'm the only one! I too don't know what to say to my users, other than Apple have a bug and they are working on it, with no timescale for resolution. People are not happy! It was working perfectly well in iOS14. Now it's not in iOS15. Instruments suggests to me that there is probably a memory leak in NSPersistentCloudKitContainer. Large spikes in Virtual Memory usage on all imports (even the small ones) but the small ones dont trigger a crash. The same (smallish) database in iOS14 uses 36MB of VM but in iOS15 uses 1.49GB for example!!
Replies
Boosts
Views
Activity
Mar ’22
Reply to WidgetKit and CoreData/CloudKit
I might have answered my own question. First, add a managedObject variable to the TimelineProvider and a initializer: struct Provider: IntentTimelineProvider { var managedObjectContext : NSManagedObjectContext init(context : NSManagedObjectContext) { self.managedObjectContext = context } ... Then initialize the persistentContainer within the Widget struct and pass the persistentContainer.viewContext into the new Provider initializer: struct Widget_Extension: Widget { private let kind: String = Widget_Extension public var body: some WidgetConfiguration { IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider(context: persistentContainer.viewContext), placeholder: PlaceholderView()) { entry in Widget_ExtensionEntryView(entry: entry) } .configurationDisplayName(My Widget) .description(This is an example widget.) } var persistentContainer: NSPersistentCloudKitContainer = {... return container }() The Provider now has access to your CoreData+CloudKit data.
Replies
Boosts
Views
Activity
Jun ’20