Core Data + Cloud Kit - data record type does not appear in CloudKit Dashboard

I created a blank SwiftUI project in XCode and selected to include Core Data and Cloud Kit.

By default, Apple already included some Core Data sample code and entities in the project, and also a Persistence.swift file that contained NSPersistentCloudKitContainer code.

(the sample code of Core Data is to log timestamps to a SwiftUI list, like in 05:18~06:10 of this Apple intro video: Using Core Data With CloudKit - WWDC19 - Videos - Apple Developer)

After some basic setup, supposed the data record and record type of the app can be shown on the related container of Cloud Kit dashboard, but it doesn’t.


Here is what I have done:

  • I followed the tutorial Apple Developer Documentation
  • Created the project with Core Data and Cloud Kit
  • Haven’t touch any code from the Persistence.swift file since Apple has already set it up.
  • Also haven’t touch the app struct, content view and core data entities (left all sample code untouched)
  • Selected Automatically Manage Signing and Development Team, with a paid developer acc.
  • Added iCloud Capability
  • Selected CloudKit in iCloud Capability, Created CloudKit Container.
  • Added Background Modes Capability and selected Remote Notification.

And then:

  • Launch simulator, launch app, being asked to sign in with Apple ID, and did so.
  • Add some timestamps into SwiftUI list.
  • Kill app and relaunch, the timestamps are still there, even del app and reinstall. Core Data sample code works perfectly.
  • Went to the related container of CloudKit Dashboard, selected Records, Private Database, There are only “Users” in Record Type. No other record types were shown.

Log

CoreData: debug: CoreData+CloudKit: -[PFCloudKitOptionsValidator validateOptions:andStoreOptions:error:](36): Validating options: <NSCloudKitMirroringDelegateOptions: 0x600003fd45a0> containerIdentifier:iCloud.com.ProjectName databaseScope:Private ckAssetThresholdBytes:<null> operationMemoryThresholdBytes:<null> useEncryptedStorage:NO useDeviceToDeviceEncryption:NO automaticallyDownloadFileBackedFutures:NO automaticallyScheduleImportAndExportOperations:YES skipCloudKitSetup:NO preserveLegacyRecordMetadataBehavior:NO useDaemon:YES apsConnectionMachServiceName:<null> containerProvider:<PFCloudKitContainerProvider: 0x600000fdc150> storeMonitorProvider:<PFCloudKitStoreMonitorProvider: 0x600000fdc1b0> metricsClient:<PFCloudKitMetricsClient: 0x600000fdc1f0> metadataPurger:<PFCloudKitMetadataPurger: 0x600000fdc200> scheduler:<null> notificationListener:<null> containerOptions:<null> defaultOperationConfiguration:<null> progressProvider:<NSPersistentCloudKitContainer: 0x6000018cd340> test_useLegacySavePolicy:YES archivingUtilities:<PFCloudKitArchivingUtilities: 0x600000fdc210>
storeOptions: {
    NSInferMappingModelAutomaticallyOption = 1;
    NSMigratePersistentStoresAutomaticallyOption = 1;
    NSPersistentCloudKitContainerOptionsKey = "<NSPersistentCloudKitContainerOptions: 0x6000003a4000>";
    NSPersistentHistoryTrackingKey = 1;
    NSPersistentStoreMirroringOptionsKey =     {
        NSPersistentStoreMirroringDelegateOptionKey = "<NSCloudKitMirroringDelegate: 0x6000036d0340>";
    };
}
CoreData: debug: CoreData+CloudKit: -[NSCloudKitMirroringDelegate observeChangesForStore:inPersistentStoreCoordinator:](385): <NSCloudKitMirroringDelegate: 0x6000036d0340>: Observing store: <NSSQLCore: 0x14d504650> (URL: file:///ADDRESS/PROJECT.sqlite)
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _setUpCloudKitIntegration](530): <NSCloudKitMirroringDelegate: 0x6000036d0340>: Successfully enqueued setup request.
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate checkAndExecuteNextRequest](2928): <NSCloudKitMirroringDelegate: 0x6000036d0340>: Checking for pending requests.
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate checkAndExecuteNextRequest]_block_invoke(2941): <NSCloudKitMirroringDelegate: 0x6000036d0340>: Executing: <NSCloudKitMirroringDelegateSetupRequest: 0x600001885e40> C5E6C108-29AD-4B29-B2F2-2E7B6CF17C43
CoreData: debug: CoreData+CloudKit: -[PFCloudKitMetadataModelMigrator calculateMigrationStepsWithConnection:error:](446): Skipping migration for 'ANSCKDATABASEMETADATA' because it already has a column named 'ZLASTFETCHDATE'
CoreData: debug: CoreData+CloudKit: -[PFCloudKitMetadataModelMigrator calculateMigrationStepsWithConnection:error:](503): Skipping migration for 'ANSCKMETADATAENTRY' because it already has a column named 'ZDATEVALUE'
CoreData: debug: CoreData+CloudKit: -[PFCloudKitMetadataModelMigrator calculateMigrationStepsWithConnection:error:](446): Skipping migration for 'ANSCKRECORDZONEMETADATA' because it already has a column named 'ZLASTFETCHDATE'
CoreData: debug: CoreData+CloudKit: -[PFCloudKitMetadataModelMigrator calculateMigrationStepsWithConnection:error:](462): Skipping migration for 'ANSCKRECORDZONEMETADATA' because it already has a column named 'ZSUPPORTSFETCHCHANGES'
CoreData: debug: CoreData+CloudKit: -[PFCloudKitMetadataModelMigrator calculateMigrationStepsWithConnection:error:](462): Skipping migration for 'ANSCKRECORDZONEMETADATA' because it already has a column named 'ZSUPPORTSATOMICCHANGES'
CoreData: debug: CoreData+CloudKit: -[PFCloudKitMetadataModelMigrator calculateMigrationStepsWithConnection:error:](462): Skipping migration for 'ANSCKRECORDZONEMETADATA' because it already has a column named 'ZSUPPORTSRECORDSHARING'
CoreData: debug: CoreData+CloudKit: -[PFCloudKitMetadataModelMigrator calculateMigrationStepsWithConnection:error:](462): Skipping migration for 'ANSCKRECORDZONEMETADATA' because it already has a column named 'ZSUPPORTSZONESHARING'
CoreData: debug: CoreData+CloudKit: -[PFCloudKitMetadataModelMigrator calculateMigrationStepsWithConnection:error:](479): Skipping migration for 'ANSCKRECORDZONEMETADATA' because it already has a column named 'ZNEEDSIMPORT'
CoreData: debug: CoreData+CloudKit: -[PFCloudKitMetadataModelMigrator calculateMigrationStepsWithConnection:error:](479): Skipping migration for 'ANSCKRECORDZONEMETADATA' because it already has a column named 'ZNEEDSRECOVERYFROMZONEDELETE'
CoreData: debug: CoreData+CloudKit: -[PFCloudKitMetadataModelMigrator calculateMigrationStepsWithConnection:error:](479): Skipping migration for 'ANSCKRECORDZONEMETADATA' because it already has a column named 'ZNEEDSRECOVERYFROMUSERPURGE'
CoreData: debug: CoreData+CloudKit: -[PFCloudKitMetadataModelMigrator calculateMigrationStepsWithConnection:error:](479): Skipping migration for 'ANSCKRECORDZONEMETADATA' because it already has a column named 'ZENCODEDSHAREDATA'
CoreData: debug: CoreData+CloudKit: -[PFCloudKitMetadataModelMigrator calculateMigrationStepsWithConnection:error:](479): Skipping migration for 'ANSCKRECORDZONEMETADATA' because it already has a column named 'ZNEEDSSHAREUPDATE'
CoreData: debug: CoreData+CloudKit: -[PFCloudKitMetadataModelMigrator calculateMigrationStepsWithConnection:error:](479): Skipping migration for 'ANSCKRECORDZONEMETADATA' because it already has a column named 'ZNEEDSSHAREDELETE'
CoreData: debug: CoreData+CloudKit: -[PFCloudKitMetadataModelMigrator calculateMigrationStepsWithConnection:error:](479): Skipping migration for 'ANSCKRECORDZONEMETADATA' because it already has a column named 'ZNEEDSRECOVERYFROMIDENTITYLOSS'
CoreData: CloudKit: CoreData+CloudKit: -[PFCloudKitSetupAssistant _checkUserIdentity:]_block_invoke(1235): <PFCloudKitSetupAssistant: 0x6000029c2880>: CKIdentity record matches store: <CKRecordID: 0x600000dab560; recordName=_8b74d2123c870a6cd2fb07b5c74bb4b1, zoneID=_defaultZone:__defaultOwner__>
2022-09-25 11:06:51.874997+0800 ProjectName[19841:1140864] [error] error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _performSetupRequest:]_block_invoke(1106): <NSCloudKitMirroringDelegate: 0x6000036d0340>: Failed to set up CloudKit integration for store: <NSSQLCore: 0x14d504650> (URL: file:///ADDRESS/ProjectName.sqlite)
<CKError 0x600000349440: "Partial Failure" (2/1011); "Failed to modify some record zones"; partial errors: {
	com.apple.coredata.cloudkit.zone:__defaultOwner__ = <CKError 0x6000003b0390: "Internal Error" (1/5000); "Failed to sync user keys">
}>
CoreData: error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _performSetupRequest:]_block_invoke(1106): <NSCloudKitMirroringDelegate: 0x6000036d0340>: Failed to set up CloudKit integration for store: <NSSQLCore: 0x14d504650> (URL: file:///ADDRESS/PROJECT.sqlite)
<CKError 0x600000349440: "Partial Failure" (2/1011); "Failed to modify some record zones"; partial errors: {
	com.apple.coredata.cloudkit.zone:__defaultOwner__ = <CKError 0x6000003b0390: "Internal Error" (1/5000); "Failed to sync user keys">
}>
2022-09-25 11:06:51.875077+0800 ProjectName[19841:1140864] [error] error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate recoverFromError:](2115): <NSCloudKitMirroringDelegate: 0x6000036d0340> - Attempting recovery from error: <CKError 0x600000349440: "Partial Failure" (2/1011); "Failed to modify some record zones"; partial errors: {
	com.apple.coredata.cloudkit.zone:__defaultOwner__ = <CKError 0x6000003b0390: "Internal Error" (1/5000); "Failed to sync user keys">
}>
CoreData: error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate recoverFromError:](2115): <NSCloudKitMirroringDelegate: 0x6000036d0340> - Attempting recovery from error: <CKError 0x600000349440: "Partial Failure" (2/1011); "Failed to modify some record zones"; partial errors: {
	com.apple.coredata.cloudkit.zone:__defaultOwner__ = <CKError 0x6000003b0390: "Internal Error" (1/5000); "Failed to sync user keys">
}>
2022-09-25 11:06:51.875317+0800 ProjectName[19841:1140864] [error] error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _recoverFromPartialError:forStore:inMonitor:]_block_invoke(2464): <NSCloudKitMirroringDelegate: 0x6000036d0340>: Found unknown error as part of a partial failure: <CKError 0x6000003b0390: "Internal Error" (1/5000); "Failed to sync user keys">
CoreData: error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _recoverFromPartialError:forStore:inMonitor:]_block_invoke(2464): <NSCloudKitMirroringDelegate: 0x6000036d0340>: Found unknown error as part of a partial failure: <CKError 0x6000003b0390: "Internal Error" (1/5000); "Failed to sync user keys">
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _finishedRequest:withResult:](2959): Finished request: <NSCloudKitMirroringDelegateSetupRequest: 0x600001885e40> C5E6C108-29AD-4B29-B2F2-2E7B6CF17C43 with result: <NSCloudKitMirroringResult: 0x600000d8e7e0> success: 0 madeChanges: 0 error: <CKError 0x600000349440: "Partial Failure" (2/1011); "Failed to modify some record zones"; partial errors: {
	com.apple.coredata.cloudkit.zone:__defaultOwner__ = <CKError 0x6000003b0390: "Internal Error" (1/5000); "Failed to sync user keys">
}>
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate checkAndExecuteNextRequest](2928): <NSCloudKitMirroringDelegate: 0x6000036d0340>: Checking for pending requests.
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate checkAndExecuteNextRequest]_block_invoke(2944): <NSCloudKitMirroringDelegate: 0x6000036d0340>: No more requests to execute.

Persistent container struct code from Apple just in case

import CoreData

struct PersistenceController {
    static let shared = PersistenceController()

    static var preview: PersistenceController = {
        let result = PersistenceController(inMemory: true)
        let viewContext = result.container.viewContext
        for _ in 0..<10 {
            let newItem = Item(context: viewContext)
            newItem.timestamp = Date()
        }
        do {
            try viewContext.save()
        } catch {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }
        return result
    }()

    let container: NSPersistentCloudKitContainer

    init(inMemory: Bool = false) {
        container = NSPersistentCloudKitContainer(name: "ProjectName")
        if inMemory {
            container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
        }
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

                /*
                 Typical reasons for an error here include:
                 * The parent directory does not exist, cannot be created, or disallows writing.
                 * The persistent store is not accessible, due to permissions or data protection when the device is locked.
                 * The device is out of space.
                 * The store could not be migrated to the current model version.
                 Check the error message to determine what the actual problem was.
                 */
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        container.viewContext.automaticallyMergesChangesFromParent = true
    }
}

I found the solution… DEPLOY TO A REAL IPHONE, don’t do it on simulator…

everything works fine then.

1 Like