Background
I have an established app in the App Store which has been using NSPersistentCloudkitContainer since iOS 13 without any issues.
I've been running my app normally on an iOS device running the iOS 15 betas, mainly to see problems arise before my users see them.
Ever since iOS 15 (beta 4) my app has failed to sync changes - no matter how small the change. An upload 'starts' but never completes. After a minute or so the app quits to the Home Screen and no useful information can be gleaned from crash reports. Until now I've had no idea what's going on.
Possible Bug in the API?
I've managed to replicate this behaviour on the simulator and on another device when building my app with Xcode 13 (beta 5) on iOS 15 (beta 5).
It appears that NSPersistentCloudkitContainer has a memory leak and keeps ramping up the RAM consumption (and CPU at 100%) until the operating system kills the app. No code of mine is running.
I'm not really an expert on these things and I tried to use Instruments to see if that would show me anything. It appears to be related to NSCloudkitMirroringDelegate getting 'stuck' somehow but I have no idea what to do with this information.
My Core Data database is not tiny, but not massive by any means and NSPersistentCloudkitContainer has had no problems syncing to iCloud prior to iOS 15 (beta 4).
If I restore my App Data (from an external backup file - 700MB with lots of many-many, many-one relationships, ckAssets, etc.) the data all gets added to Core Data without an issue at all. The console log (see below) then shows that a sync is created, scheduled & then started... but no data is uploaded.
At this point the memory consumption starts and all I see is 'backgroundTask' warnings appear (only related to CloudKit) with no code of mine running.
CoreData: CloudKit: CoreData+CloudKit: -[PFCloudKitExporter analyzeHistoryInStore:withManagedObjectContext:error:](501): <PFCloudKitExporter: 0x600000301450>: Exporting changes since (0): <NSPersistentHistoryToken - {
"4B90A437-3D96-4AC9-A27A-E0F633CE5D9D" = 906;
}>
CoreData: CloudKit: CoreData+CloudKit: -[PFCloudKitExportContext processAnalyzedHistoryInStore:inManagedObjectContext:error:]_block_invoke_3(251): Finished processing analyzed history with 29501 metadata objects to create, 0 deleted rows without metadata.
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _scheduleAutomatedExportWithLabel:activity:completionHandler:](2800): <NSCloudKitMirroringDelegate: 0x6000015515c0> - Beginning automated export - ExportActivity:
<CKSchedulerActivity: 0x60000032c500; containerID=<CKContainerID: 0x600002ed3240; containerIdentifier=iCloud.com.nitramluap.Somnus, containerEnvironment="Sandbox">, identifier=com.apple.coredata.cloudkit.activity.export.4B90A437-3D96-4AC9-A27A-E0F633CE5D9D, priority=2, xpcActivityCriteriaOverrides={ Priority=Utility }>
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate executeMirroringRequest:error:](765): <NSCloudKitMirroringDelegate: 0x6000015515c0>: Asked to execute request: <NSCloudKitMirroringExportRequest: 0x600002ed2a30> CBE1852D-7793-46B6-8314-A681D2038B38
2021-08-13 08:41:01.518422+1000 Somnus[11058:671570] [BackgroundTask] Background Task 68 ("CoreData: CloudKit Export"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.
2021-08-13 08:41:03.519455+1000 Somnus[11058:671570] [BackgroundTask] Background Task 154 ("CoreData: CloudKit Scheduling"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this.
Just wondering if anyone else is having a similar issue? It never had a problem syncing an initial database restore prior to iOS 15 (beta 4) and the problems started right after installing iOS 15 (beta 4).
I've submitted this to Apple Feedback and am awaiting a response (FB9412346). If this is unfixable I'm in real trouble (and my users are going to be livid).
Thanks in advance!
iCloud & Data
RSS for tagLearn how to integrate your app with iCloud and data frameworks for effective data storage
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I have been working on an app for the past few months, and one issue that I have encountered a few times is an error where quick subsequent deletions cause issues with detached tasks that are triggered from some user actions.
Inside a Task.detached, I am building an isolated model context, querying for LineItems, then iterating over those items. The crash happens when accessing a Transaction property through a relationship.
var byTransactionId: [UUID: [LineItem]] {
return Dictionary(grouping: self) { item in
item.transaction?.id ?? UUID()
}
}
In this case, the transaction has been deleted, but the relationship existed when the fetch occurred, so the transaction value is non-nil. The crash occurs when accessing the id. This is the error.
SwiftData/BackingData.swift:1035: Fatal error: This model instance was invalidated because its backing data could no longer be found the store. PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(backing: SwiftData.PersistentIdentifier.PersistentIdentifierBacking.managedObjectID(0xb43fea2c4bc3b3f5 <x-coredata://A9EFB8E3-CB47-48B2-A7C4-6EEA25D27E2E/Transaction/p1756>)))
I see other posts about this error and am exploring some suggestions, but if anyone has any thoughts, they would be appreciated.
I have a Package.swift file that builds and runs from Xcode 15.2 without issue but fails to compile when built from the command line ("swift build"). The swift version is 6.0.3. I'm at wits end trying to diagnose this and would welcome any thoughts.
The error in question is
error: external macro implementation type 'SwiftDataMacros.PersistentModelMacro' could not be found for macro 'Model()'; plugin for module 'SwiftDataMacros' not found
The code associated with the module is very vanilla.
import Foundation
import SwiftData
@Model
public final class MyObject {
@Attribute(.unique) public var id:Int64
public var vertexID:Int64
public var updatedAt:Date
public var codeUSRA:Int32
init(id:Int64, vertexID:Int64, updatedAt:Date, codeUSRA:Int32) {
self.id = id
self.vertexID = vertexID
self.updatedAt = updatedAt
self.codeUSRA = codeUSRA
}
public static func create(id:Int64, vertexID:Int64, updatedAt:Date, codeUSRA:Int32) -> MyObject {
MyObject(id: id, vertexID: vertexID, updatedAt: updatedAt, codeUSRA: codeUSRA)
}
}
Thank you.
I'm developing a SwiftUI app using SwiftData and encountering a persistent issue:
Error Message:
Thread 1: Fatal error: Duplicate keys of type 'Bland' were found in a Dictionary.
This usually means either that the type violates Hashable's requirements, or that members of such a dictionary were mutated after insertion.
Details:
Occurrence: The error always occurs on the first launch of the app after installation. Specifically, it happens approximately 1 minute after the app starts.
Inconsistent Behavior: Despite no changes to the code or server data, the error occurs inconsistently.
Data Fetching Process:
I fetch data for entities (Bland, CrossZansu, and Trade) from the server using the following process:
Fetch Bland and CrossZansu entities via URLSession.
Insert or update these entities into the SwiftData context.
The fetched data is managed as follows:
func refleshBlandsData() async throws {
if let blandsOnServer = try await DataModel.shared.getBlands() {
await MainActor.run {
blandsOnServer.forEach { blandOnServer in
if let blandOnLocal = blandList.first(where: { $0.code == blandOnServer.code }) {
blandOnLocal.update(serverBland: blandOnServer)
} else {
modelContext.insert(blandOnServer.bland)
}
}
}
}
}
This is a simplified version of my StockListView. The blandList is a @Query property and dynamically retrieves data from SwiftData:
struct StockListView: View {
@Environment(\.modelContext) private var modelContext
@Query(sort: \Bland.sname) var blandList: [Bland]
@Query var users: [User]
@State private var isNotLoaded = true
@State private var isLoading = false
@State private var loadingErrorState = ""
var body: some View {
NavigationStack {
List {
ForEach(blandList, id: \.self) { bland in
NavigationLink(value: bland) {
Text(bland.sname)
}
}
}
.navigationTitle("Stock List")
.onAppear {
doIfFirst()
}
}
}
// This function handles data loading when the app launches for the first time
func doIfFirst() {
if isNotLoaded {
loadDataWithAnimationIfNotLoading()
isNotLoaded = false
}
}
// This function ensures data is loaded with an animation and avoids multiple triggers
func loadDataWithAnimationIfNotLoading() {
if !isLoading {
isLoading = true
Task {
do {
try await loadData()
} catch {
// Capture and store any errors during data loading
loadingErrorState = "Data load failed: \(error.localizedDescription)"
}
isLoading = false
}
}
}
// Fetch data from the server and insert it into the SwiftData model context
func loadData() async throws {
if let blandsOnServer = try await DataModel.shared.getBlands() {
for bland in blandsOnServer {
// Avoid inserting duplicate keys by checking for existing items in blandList
if !blandList.contains(where: { $0.code == bland.code }) {
modelContext.insert(bland.bland)
}
}
}
}
}
Entity Definitions:
Here are the main entities involved:
Bland:
@Model
class Bland: Identifiable {
@Attribute(.unique) var code: String
var sname: String
@Relationship(deleteRule: .cascade, inverse: \CrossZansu.bland)
var zansuList: [CrossZansu]
@Relationship(deleteRule: .cascade, inverse: \Trade.bland)
var trades: [Trade]
}
CrossZansu:
@Model
class CrossZansu: Equatable {
@Attribute(.unique) var id: String
var bland: Bland?
}
Trade:
@Model
class Trade {
@Relationship(deleteRule: .nullify)
var user: User?
var bland: Bland
}
User:
class User {
var id: UUID
@Relationship(deleteRule: .cascade, inverse: \Trade.user)
var trades: [Trade]
}
Observations:
Error Context: The error occurs after the data is fetched and inserted into SwiftData. This suggests an issue with Hashable requirements or duplicate keys being inserted unintentionally.
Concurrency Concerns: The fetch and update operations are performed in asynchronous tasks. Could this cause race conditions?
Questions:
Could this issue be related to how @Relationship and @Attribute(.unique) are managed in SwiftData?
What are potential pitfalls with Equatable implementations (e.g., in CrossZansu) when used in SwiftData entities?
Are there any recommended approaches for debugging "Duplicate keys" errors in SwiftData?
Additional Info:
Error Timing: The error occurs only during the app's first launch and consistently within the first minute.
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.)
I'm using SwiftData with CloutKit with a very simple app. Data syncs between iOS, iPadOS, and visionOS, but not macOS. From what I can tell, macOS is never getting CK messages unless I'm running the app from Xcode.
I can listen for the CK messages and show a line in a debug overlay. This works perfectly when I run from Xcode. I can see the notifications and see updates in my app. However, if I just launch the app outside of Xcode I will never see any changes or notifications. It is as if the Mac app never even tries to contact CloudKit.
Schema has been deployed in the CloudKit console. The app is based on the multi-platform Xcode template. Again, only the macOS version has this issue. Is there some extra permission or setting I need to set up in order to use CloudKit on macOS?
@State private var publisher = NotificationCenter.default.publisher(for: NSPersistentCloudKitContainer.eventChangedNotification).receive(on: DispatchQueue.main)
.onReceive(publisher) { notification in
// Listen for changes in CK events
if let userInfo = notification.userInfo,
let event = userInfo[NSPersistentCloudKitContainer.eventNotificationUserInfoKey] as? NSPersistentCloudKitContainer.Event {
let message = "CloudKit Sync: \(event.type.rawValue) - \(event.succeeded ? "Success" : "Failed") - \(event.description)"
// Store for UI display
syncNotifications.append(message)
if syncNotifications.count > 10 {
syncNotifications.removeFirst()
}
}
}
.overlay(alignment: .topTrailing) {
if !syncNotifications.isEmpty {
VStack(alignment: .leading) {
ForEach(syncNotifications, id: \.self) { notification in
Text(notification)
.padding(8)
}
}
.frame(width: 800, height: 500)
.cornerRadius(8)
.background(Color.secondary.opacity(0.2))
.padding()
.transition(.move(edge: .top))
}
}
Problem
The following code doesn't work:
let predicate = #Predicate<Car> { car in
car.size == size //This doesn't work
}
Console Error
Query encountered an error: SwiftData.SwiftDataError(_error: SwiftData.SwiftDataError._Error.unsupportedPredicate)
Root cause
Size is an enum, #Predicate works with other type such as String however doesn't work with enum
Enum value is saved however is not filtered by #Predicate
Environment
Xcode: 15.0 (15A240d) - App Store
macOS: 14.0 (23A339) - Release Candidate
Steps to reproduce
Run the app on iOS 17 or macOS Sonoma
Press the Add button
Notice that the list remains empty
Expected behaviour
List should show the newly created small car
Actual behaviour
List remains empty inspite of successfully creating the small car.
Feedback
FB13194334
Code
Size
enum Size: String, Codable {
case small
case medium
case large
}
Car
import SwiftData
@Model
class Car {
let id: UUID
let name: String
let size: Size
init(
id: UUID,
name: String,
size: Size
) {
self.id = id
self.name = name
self.size = size
}
}
ContentView
struct ContentView: View {
var body: some View {
NavigationStack {
CarList(size: .small)
}
}
CarList
import SwiftUI
import SwiftData
struct CarList: View {
let size: Size
@Environment(\.modelContext)
private var modelContext
@Query
private var cars: [Car]
init(size: Size) {
self.size = size
let predicate = #Predicate<Car> { car in
car.size == size //This doesn't work
}
_cars = Query(filter: predicate, sort: \.name)
}
var body: some View {
List(cars) { car in
VStack(alignment: .leading) {
Text(car.name)
Text("\(car.size.rawValue)")
Text(car.id.uuidString)
.font(.footnote)
}
}
.toolbar {
Button("Add") {
createCar()
}
}
}
private func createCar() {
let name = "aaa"
let car = Car(
id: UUID(),
name: name,
size: size
)
modelContext.insert(car)
}
}
Hi,
I did cloudkit synchronization using swiftdata.
However, synchronization does not occur automatically, and synchronization occurs intermittently only when the device is closed and opened.
For confirmation, after changing the data in Device 1 (saving), when the data is fetched from Device 2, there is no change.
I've heard that there's still an issue with swiftdata sync and Apple is currently troubleshooting it, is the phenomenon I'm experiencing in the current version normal?
The following complex migration consistently crashes the app with the following error:
SwiftData/PersistentModel.swift:726: Fatal error: What kind of backing data is this? SwiftData._KKMDBackingData<SwiftDataMigration.ItemSchemaV1.ItemList>
My app relies on a complex migration that involves these optional 1 to n relationships. Theoretically I could not assign the relationships in the willMigrate block but afterwards I am not able to tell which list and items belonged together.
Steps to reproduce:
Run project
Change typealias CurrentSchema to ItemSchemaV2 instead of ItemSchemaV1.
Run project again -> App crashes
My setup:
Xcode Version 16.2 (16C5032a)
MacOS Sequoia 15.4
iPhone 12 with 18.3.2 (22D82)
Am I doing something wrong or did I stumble upon a bug? I have a demo Xcode project ready but I could not upload it here so I put the code below.
Thanks for your help
typealias CurrentSchema = ItemSchemaV1
typealias ItemList = CurrentSchema.ItemList
typealias Item = CurrentSchema.Item
@main
struct SwiftDataMigrationApp: App {
var sharedModelContainer: ModelContainer = {
do {
return try ModelContainer(for: ItemList.self, migrationPlan: MigrationPlan.self)
} catch {
fatalError("Could not create ModelContainer: \(error)")
}
}()
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(sharedModelContainer)
}
}
This is the migration plan
enum MigrationPlan: SchemaMigrationPlan {
static var schemas: [any VersionedSchema.Type] {
[ItemSchemaV1.self, ItemSchemaV2.self]
}
static var stages: [MigrationStage] = [
MigrationStage.custom(fromVersion: ItemSchemaV1.self, toVersion: ItemSchemaV2.self, willMigrate: { context in
print("Started migration")
let oldlistItems = try context.fetch(FetchDescriptor<ItemSchemaV1.ItemList>())
for list in oldlistItems {
let items = list.items.map { ItemSchemaV2.Item(timestamp: $0.timestamp)}
let newList = ItemSchemaV2.ItemList(items: items, name: list.name, note: "This is a new property")
context.insert(newList)
context.delete(list)
}
try context.save() // Crash indicated here
print("Finished willMigrate")
}, didMigrate: { context in
print("Did migrate successfully")
})
]
}
The versioned schemas
enum ItemSchemaV1: VersionedSchema {
static var versionIdentifier = Schema.Version(1, 0, 0)
static var models: [any PersistentModel.Type] {
[Item.self]
}
@Model
final class Item {
var timestamp: Date
var list: ItemSchemaV1.ItemList?
init(timestamp: Date) {
self.timestamp = timestamp
}
}
@Model
final class ItemList {
@Relationship(deleteRule: .cascade, inverse: \ItemSchemaV1.Item.list)
var items: [Item]
var name: String
init(items: [Item], name: String) {
self.items = items
self.name = name
}
}
}
enum ItemSchemaV2: VersionedSchema {
static var versionIdentifier = Schema.Version(2, 0, 0)
static var models: [any PersistentModel.Type] {
[Item.self]
}
@Model
final class Item {
var timestamp: Date
var list: ItemSchemaV2.ItemList?
init(timestamp: Date) {
self.timestamp = timestamp
}
}
@Model
final class ItemList {
@Relationship(deleteRule: .cascade, inverse: \ItemSchemaV2.Item.list)
var items: [Item]
var name: String
var note: String
init(items: [Item], name: String, note: String = "") {
self.items = items
self.name = name
self.note = note
}
}
}
Last the ContentView:
struct ContentView: View {
@Query private var itemLists: [ItemList]
var body: some View {
NavigationSplitView {
List {
ForEach(itemLists) { list in
NavigationLink {
List(list.items) { item in
Text(item.timestamp.formatted(date: .abbreviated, time: .complete))
}
.navigationTitle(list.name)
} label: {
Text(list.name)
}
}
}
.navigationTitle("Crashing migration demo")
.onAppear {
if itemLists.isEmpty {
for index in 0..<10 {
let items = [Item(timestamp: Date.now)]
let listItem = ItemList(items: items, name: "List No. \(index)")
modelContext.insert(listItem)
}
try! modelContext.save()
}
}
} detail: {
Text("Select an item")
}
}
}
I have been using the basic NSPersistentContainer with 100k+ records for a while now with no issues. The database size can fluctuate a bit but on average it takes up about 22mb on device.
When I switch the container to NSPersistentCloudKitContainer, I see a massive increase in size to ~150mb initially. As the sync engine uploads records to iCloud it has ballooned to over 600mb on device. On top of that, the user's iCloud usage in settings reports that it takes up 1.7gb in the cloud.
I understand new tables are added and history tracking is enabled but the size increase seems a bit drastic. I'm not sure how we got from 22mb to 1.7gb with the exact same data.
A few other things that are important to note:
I import all the 100k+ records at once when testing the different containers. At the time of the initial import there is only 1 relation (an import group record) that all the records are attached to.
I save the background context only once after all the records and the import group have been made and added to the context.
After the initial import, some of these records may have a few new relations added to them over time. I suppose this could be causing some of the size increase, but its only about 20,000 records that are updated.
None of the records include files/ large binary data.
Most of the attributes are encrypted.
I'm syncing to the dev iCloud environment.
When I do make a change to a single attribute in a record, CloudKit reports that every attribute has been modified (not sure if this is normal or not )
Also, When syncing to a new device, the sync can take hours - days. I'm guessing it's having to sync both the new records and the changes, but it exponentially gets slower as more records are downloaded. The console will show syncing activity, but new records are being added at a slower rate as more records are added. After about 50k records, it grinds to a halt and while the console still shows sync activity, only about 100 records are added every hour.
All this to say i'm very confused where these issues are coming from. I'm sure its a combination of how i've setup my code and the vast record count, record history, etc.
If anyone has any ideas it would be much appreciated.
Every time I insert a subclass (MYShapeLayer) into the model context, the app crashes with an error:
DesignerPlayground crashed due to fatalError in BackingData.swift at line 908. Never access a full future backing data - PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(backing: SwiftData.PersistentIdentifier.PersistentIdentifierBacking.managedObjectID(0xb2dbc55f3f4c57f2 <x-coredata://B1E3206B-40DE-4185-BC65-4540B4705B40/MYShapeLayer/p1>))) with Optional(A6CA4F89-107F-4A66-BC49-DD7DAC689F77)
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@Query private var designs: [MYDesign]
var layers: [MYLayer] {
designs.first?.layers ?? []
}
var body: some View {
NavigationStack {
List {
ForEach(layers) { layer in
Text(layer.description)
}
}
.onAppear {
let design = MYDesign(title: "My Design")
modelContext.insert(design)
try? modelContext.save()
}
.toolbar {
Menu("Add", systemImage: "plus") {
Button(action: addTextLayer) {
Text("Add Text Layer")
}
Button(action: addShapeLayer) {
Text("Add Shape Layer")
}
}
}
}
}
private func addTextLayer() {
if let design = designs.first {
let newLayer = MYLayer(order: layers.count, kind: .text)
newLayer.design = design
modelContext.insert(newLayer)
try? modelContext.save()
}
}
private func addShapeLayer() {
if let design = designs.first {
let newLayer = MYShapeLayer(shapeName: "Ellipse", order: layers.count)
newLayer.design = design
modelContext.insert(newLayer)
try? modelContext.save()
}
}
}
#Preview {
ContentView()
.modelContainer(for: [MYDesign.self, MYLayer.self, MYShapeLayer.self], inMemory: true)
}
@Model
final class MYDesign {
var title: String = ""
@Relationship(deleteRule: .cascade, inverse: \MYLayer.design)
var layers: [MYLayer] = []
init(title: String = "") {
self.title = title
}
}
@available(iOS 26.0, macOS 26.0, *)
@Model
class MYLayer {
var design: MYDesign!
var order: Int = 0
var title: String = ""
init(order: Int = 0, title: String = "New Layer") {
self.order = order
self.title = title
}
}
@available(iOS 26.0, macOS 26.0, *)
@Model
class MYShapeLayer: MYLayer {
var shapeName: String = ""
init(shapeName: String, order: Int = 0) {
self.shapeName = shapeName
super.init(order: order)
}
}
I am working on a SwiftUI project using Core Data. I have an entity called AppleUser in my data model, with the following attributes: id (UUID), name (String), email (String), password (String), and createdAt (Date). All attributes are non-optional.
I created the corresponding Core Data class files (AppleUser+CoreDataClass.swift and AppleUser+CoreDataProperties.swift) using Xcode’s automatic generation. I also have a PersistenceController that initializes the NSPersistentContainer with the model name JobLinkModel.
When I try to save a new AppleUser object using:
let user = AppleUser(context: viewContext)
user.id = UUID()
user.name = "User1"
user.email = "..."
user.password = "password1"
user.createdAt = Date()【The email is correctly formatted, but it has been replaced with “…” for privacy reasons】
try? viewContext.save()
I get the following error in the console:Core Data save failed: Foundation._GenericObjCError.nilError, [:]
User snapshot: ["id": ..., "name": "User1", "email": "...", "password": "...", "createdAt": ...]
All fields have valid values, and the Core Data model seems correct. I have also tried:
• Checking that the model name in NSPersistentContainer(name:) matches the .xcdatamodeld file (JobLinkModel)
• Ensuring the AppleUser entity Class, Module, and Codegen are correctly set (Class Definition, Current Product Module)
• Deleting duplicate or old AppleUser class files
• Cleaning Xcode build folder and deleting the app from the simulator
• Using @Environment(.managedObjectContext) for the context
Despite all this, I still get _GenericObjCError.nilError when saving a new AppleUser object.
I want to understand:
1. Why is Core Data failing to save even though all fields are non-nil and correctly assigned?
2. Could this be caused by some residual old class files, or is there something else in the setup that I am missing?
3. What steps should I take to ensure that Core Data properly recognizes the AppleUser entity and allows saving?
Any help or guidance would be greatly appreciated.
Hi, would it be possible that instead of crashing when calling fetchHistory that function simply throws an error instead?
fetchHistory seems to crash when it cannot understand the models if they are not compatible etc… which is understandable, but it makes it really difficult to handle and debug, there's not a lot of details, and honestly I would just rather that it throws an error and let me ignore a history entry that might be useless rather than crashing the entire app.
Thank you!
I'm seeing a lot of these in my logs:
PersistentIdentifier PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(url: x-swiftdata://Course/BC9CF99A-DE6A-46F1-A18D-8034255A56D8), implementation: SwiftData.PersistentIdentifierImplementation) was remapped to a temporary identifier during save: PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(url: x-coredata:///Course/t58C849CD-D895-4773-BF53-3F63CF48935B210), implementation: SwiftData.PersistentIdentifierImplementation). This is a fatal logic error in DefaultStore
... though everything seems to work.
Does anyone know what this means in this context? Anything I can do to not have this appear?
Hello Apple Team,
We’re building a CloudKit-enabled Core Data app and would like clarification on the behavior and performance characteristics of Binary Data attributes with “Allows External Storage” enabled when used with NSPersistentCloudKitContainer.
Initially, we tried storing image files manually on disk and only saving the metadata (file URLs, dimensions, etc.) in Core Data. While this approach reduced the size of the Core Data store, it introduced instability after app updates and broke sync between devices. We would prefer to use the official Apple-recommended method and have Core Data manage image storage and CloudKit syncing natively.
Specifically, we’d appreciate guidance on the following:
When a Binary Data attribute is marked as “Allows External Storage”, large image files are stored as separate files on device rather than inline in the SQLite store.
How effective is this mechanism in keeping the Core Data store size small on device?
Are there any recommended size thresholds or known limits for how many externally stored blobs can safely be managed this way?
How are these externally stored files handled during CloudKit sync?
Does each externally stored Binary Data attribute get mirrored to CloudKit as a CKAsset?
Does external storage reduce the sync payload size or network usage, or is the full binary data still uploaded/downloaded as part of the CKAsset?
Are there any bandwidth implications for users syncing via their private CloudKit database, versus developer costs in the public CloudKit database?
Is there any difference in CloudKit or Core Data behavior when a Binary Data attribute is managed this way versus manually storing image URLs and handling the file separately on disk?
Our goal is to store user-generated images efficiently and safely sync them via CloudKit, without incurring excessive local database bloat or CloudKit network overhead.
Any detailed guidance or internal performance considerations would be greatly appreciated.
Thank you,
Paul Barry
Founder & Lead Developer — Boat Buddy / Vessel Buddy iOS App
Archipelago Environmental Solutions Inc.
I have some code which handles doing some computation on a background thread before updating Core Data NSManagedObjects by using the NSManagedObjectContext.perform functions.
This code is covered in Sendable warnings in Xcode 26 (beta 6) because my NSManagedObject subclasses (autogenerated) are non-Sendable and NSManagedObjectContext.perform function takes a Sendable closure.
But I can't really figure out what I should be doing. I realize this pattern is non-ideal for Swift concurrency, but it's what Core Data demands AFAIK. How do I deal with this?
let moc = object.managedObjectContext!
try await moc.perform {
object.completed = true // Capture of 'object' with non-Sendable type 'MySpecialObject' in a '@Sendable' closure
try moc.save()
}
Thanks in advance for your help!
SwiftData ModelContainer instances don't seem to have a value for setting the Data Protection class.
Is the best way to set that by setting the Data Protection in the app capabilities? Is that the only way?
I have a need for log data that would be "Complete unless open" and user data that would be "Complete", but how do I change one of the containers data protection class?
What have people's experience with converting locally stored app data to a more browser based accessible format? Firebase seems expensive, Subabase a bit more challenging, and CloudKit too restrictive.
Hi,
I've been using Core Data + CloudKit via NSPersistentCloudKitContainer for several years now. Back then I just created my Core Data AND CloudKit fields by hand.
Now the time has come for a little lightweight migration to a new Core Data model, let's say I just needed to add one String attribute.
So I've done the Core Data local migration as usual, then added this to container code:
try? persistentContainer.initializeCloudKitSchema(options: NSPersistentCloudKitContainerSchemaInitializationOptions())
Run. And everything worked great. but…
Now I've noticed that CloudKit created new CKAsset fields for each String attribute that I had in Core Data (about 5 new CKAsset fields). Is this normal!? Why?
! Is it safe to deploy these changes to prod?
ty.
ChatGPT said: "This field is used internally by CloudKit to handle large string values. If the string value is small enough, it is stored in the normal String field, but if it exceeds the size limit (about 1KB), the string is automatically stored as a CKAsset."
Since publishing new record types to my CloudKit schema in production, a previously unchanged record type has stopped indexing new records.
While records of this type are successfully saved without errors, they are not returned in query results—they can only be accessed directly via their recordName. This issue occurs exclusively in the Production environment, both in the CloudKit Console and our iOS app.
The problem began on July 21, 2025, and continues to persist. The issue affects only new records of this specific record type; all other types are indexing and querying as expected.
The affected record's fields are properly configured with the appropriate index types (e.g., QUERYABLE) and have been not been modified prior to publishing the schema.
With this, are there any steps I should take to restore indexing functionality for this record type in Production? There have been new records inserted, and I would prefer to not have to reset the production database, if possible.
Topic:
App & System Services
SubTopic:
iCloud & Data
Tags:
CloudKit
Cloud and Local Storage
CloudKit Dashboard
CloudKit Console