Starting 20th March 2025, I see an increase in bandwidth and latency for one of my CloudKit projects.
I'm using NSPersistentCloudKitContainer to synchronise my data.
I haven't changed any CloudKit scheme during that time but shipped an update. Since then, I reverted some changes from that update, which could have led to changes in the sync behaviour.
Is anyone else seeing any issues?
I would love to file a DTS and use one of my credits for that, but unfortunately, I can't because I cannot reproduce it with a demo project because I cannot travel back in time and check if it also has an increase in metrics during that time.
Maybe an Apple engineer can green-light me filing a DTS request, please.
                    
                  
                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
                    
                      Both appleIDs(create and modify/save) sign in iCloud.
I use the following code to modify and save records:
self.containerIdentifier).publicCloudDatabase
database.fetch(withRecordID: CKRecord.ID(recordName:groupID), completionHandler: { record, error in
            if error == nil && record != nil {
                if let iDs : [String] = record!.object(forKey: "memberIDs") as? Array {
                       if iDs.count < self.maxMemberCount {
                            if let mems: [String] = record!.object(forKey: "memberNames") as? Array {
                                if !(mems as NSArray).contains(name) {
                                    var members = mems
                                    members.append(name)
                                    record!.setObject(members as CKRecordValue, forKey: "memberNames")
                                    var iDs : [String] = record!.object(forKey: "memberIDs") as! Array
                                    iDs.append(self.myMemberID)
                                    record!.setObject(iDs as CKRecordValue, forKey:"memberIDs")
                                    database.save(record!, completionHandler: { record, error in
                                        if error == nil {
                                         } else {
                                            completion(error as NSError?)
                                            dPrint("Error : \(String(describing: error))")
                                        }
                                    })
                                }else{
                                    let DBError : NSError = NSError(domain: "DBError", code: 89, userInfo: ["localizedDescription": NSLocalizedString("Your nickname already used.", comment:"")])
                                    completion(DBError)
                                    print("change your nickname")
                                }
                            }else{
                                print("group DB error")
                                let DBError : NSError = NSError(domain: "DBError", code: 88, userInfo: ["localizedDescription": NSLocalizedString("Please try later.", comment:"")])
                                completion(DBError)
                            }
                }
            }else{
                print("Error : \(String(describing: error))")
            }
        })
I received the following error message:
?Error saving records: <CKError 0x600000bbe970: "Service Unavailable" (6/NSCocoaErrorDomain:4099); "Error connecting to CloudKit daemon. This could happen for many reasons, for example a daemon exit, a device reboot, a race with the connection inactivity monitor, invalid entitlements, and more. Check the logs around this time to investigate the cause of this error."; Retry after 5.0 seconds>
baseNSError@0	NSError	domain: "CKErrorDomain" - code: 6
_userInfo	__NSDictionaryI *	4 key/value pairs	0x000060000349e300
[0]	(null)	"NSLocalizedDescription" : "Error connecting to CloudKit daemon. This could happen for many reasons, for example a daemon exit, a device reboot, a race with the connection inactivity monitor, invalid entitlements, and more. Check the logs around this time to investigate the cause of this error."
key	__NSCFConstantString *	"NSLocalizedDescription"	0x00000001117155a0
value	__NSCFConstantString *	"Error connecting to CloudKit daemon. This could happen for many reasons, for example a daemon exit, a device reboot, a race with the connection inactivity monitor, invalid entitlements, and more. Check the logs around this time to investigate the cause of this error."	0x000000011057e700
[1]	(null)	"CKRetryAfter" : Int32(5)
key	__NSCFConstantString *	"CKRetryAfter"	0x000000011057c680
value	NSConstantIntegerNumber?	Int32(5)	0x00000001105c2ed0
[2]	(null)	"CKErrorDescription" : "Error connecting to CloudKit daemon. This could happen for many reasons, for example a daemon exit, a device reboot, a race with the connection inactivity monitor, invalid entitlements, and more. Check the logs around this time to investigate the cause of this error."
key	__NSCFConstantString *	"CKErrorDescription"	0x0000000110568d00
value	__NSCFConstantString *	"Error connecting to CloudKit daemon. This could happen for many reasons, for example a daemon exit, a device reboot, a race with the connection inactivity monitor, invalid entitlements, and more. Check the logs around this time to investigate the cause of this error."	0x000000011057e700
[3]	(null)	"NSUnderlyingError" : domain: "NSCocoaErrorDomain" - code: 4099
key	__NSCFConstantString *	"NSUnderlyingError"	0x0000000111715540
value	NSError?	domain: "NSCocoaErrorDomain" - code: 4099	0x00006000016cc300
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		iCloud & Data
		
  	
                  
                
              
              
              
  
  
    
    
  
  
              
                
                
              
            
          
                    
                      I'm trying to use the new (in tvOS 26) video streaming service automatic login API from the VideoSubscriberAccount framework:
https://developer.apple.com/documentation/videosubscriberaccount/vsuseraccountmanager/autosignintoken-swift.property
It seems that this API requires an entitlement. This document suggests that the com.apple.smoot.subscriptionservice entitlement is required.
https://developer.apple.com/documentation/videosubscriberaccount/signing-people-in-to-media-apps-automatically
However, it seems more likely that com.apple.developer.video-subscriber-single-sign-on is the correct entitlement.
https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.video-subscriber-single-sign-on
Which is the correct entitlement and how do I obtain it?
I don't want to fully comply with the video partner program.
https://developer.apple.com/programs/video-partner/
I just want to use this one new automatic login feature.
                    
                  
                
                    
                      Is it possible to use CloudKit and add integrations, Google Drive for example. If possible, how?
                    
                  
                
                    
                      I have a Core Data app on the App Store that places its persistent store in the default location within the Application Support directory. At some point, I add widgets to the app while utilizing SwiftData. I create a widget extension and the app group to link both targets. I migrate my persistent store from the default location to the app group container directory. Now, the SwiftData code pointing to the shared container in the widget extension can query data. Here's the sample project for illustration up to this point.
Then, I decided to get rid of the Core Data code entirely. Move everything in the main target to SwiftData. I need to keep my persistence controller object, however, because I can never assume that the entirety of my user base has migrated. I do need to ditch the Core Data model file. Otherwise, my new SwiftData models would conflict with the auto-generated ones from that file. But once I do that, my migration code breaks. I can't set up a persistent container without the model. And I need the container for migration. SwiftData has no native interface to migrate the store to a new location. There is a line in the documentation stating that the framework copies the store to an app group container automatically. But I wasn't able to verify that claim.
                    
                  
                
                    
                      I have an app and widget that share access to a SwiftData container using App Groups. I have implemented a SwiftData migration plan, but I am unsure whether I should allow the widget to perform the migration (in addition to the app). I am concerned about two possible issues:
If the app and widget are run at approximately the same time (e.g. the user taps Open after doing a manual update in the App Store), then both the app and widget might try to perform the migration at the same time, which could lead to race conditions / data corruption.
If the widget is first to run but the widget gets suspended for some reasons (e.g., iOS decides it's using too many resources), then the migration might be suspended leaving the database in an corrupted state.
To me, it feels like the safest option is to only allow the app itself to perform the migration – this will ensure that the migration can only happen once in a safe state. However, this will lead to problems for the widget. For example, if the user does not open the app for several days after an automatic update, the widget will be in a broken state, since it will not be able to open the container until it has been migrated by the app.
Possible solutions I'm considering:
Allow both the app and widget to perform the migration and cross my fingers. (Ignore Issue 1 and Issue 2)
Implement some kind of UserDefaults flag that is set to true during migration, so that the app and widget will avoid performing the migration concurrently. (Solves Issue 1 but not Issue 2)
Only perform the migration in the app, and then add code to the widget to detect which container version the widget has access to, so that the widget can continue to work with a v1 container until the app eventually updates it to a v2 container. (Solves Issue 1 and Issue 2, but leads to very convoluted code – especially over time)
Things I'm unsure about:
Will iOS continue to use v1 of the widget until the app is opened for the first time, at which point v2 of the widget is installed? Or does iOS immediately update the widget to v2 on update? Does iOS immediately refresh the widget timeline on update?
Does SwiftData already have some logic to avoid migrations being performed twice, even from different threads? If so, how does it respond if one process tries to access a container while another process is performing a migration?
Does anyone have any recommendations about how to handle these possible issues? What are best practices?
Cheers!
                    
                  
                
                    
                      My app uses iCloud to let users sync their files via their private iCloud Drive, which does not use CloudKit.
FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appending(component: "Documents")
I plan to transfer my app to another developer account, but I'm afraid it will affect the access of the app to the existing files in that folder. Apple documentation doesn't mention this case.
Has anyone done this before and can confirm if the app will continue to work normally after transferring?
Thanks
                    
                  
                
                    
                      I'm using SwiftData, and I'm using iCloud's CloudKit feature to back up my data.
The problem here is that once you start backing up your data, you can't erase it completely.
Even if the user adds 4 data and erases 4 again, I'm using about 2.5kb.
I don't know how the user using the app will accept this.
I'm trying to provide the user with the ability to erase data at once, what should I do??
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		iCloud & Data
		
  	
                  
                
              
              
                Tags:
              
              
  
  
    
      
      
      
        
          
            CloudKit
          
        
        
      
      
    
      
      
      
        
          
            Cloud and Local Storage
          
        
        
      
      
    
      
      
      
        
          
            iCloud Drive
          
        
        
      
      
    
      
      
      
        
          
            SwiftData
          
        
        
      
      
    
  
  
              
                
                
              
            
          
                    
                      Hi,
I'm trying to sign in with Apple CloudKit.
I'm using the following code:
'use client';
import { CLOUDKIT_CONSTANTS } from '@/constants/cloudkit';
import { setCloudKitConfigured } from '@/lib/cloudkitSingleton';
import { CloudKitStatic } from '@/types/cloudkit';
import Script from 'next/script';
declare global {
  interface Window {
    CloudKit: CloudKitStatic;
  }
}
export default function Home() {
  const initializeCloudKit = async () => {
    console.info('⭐️ initializeCloudKit - start');
    // 古い認証情報を削除
    try {
      // LocalStorageから古い認証情報を削除
      const keysToRemove = [];
      for (let i = 0; i < localStorage.length; i++) {
        const key = localStorage.key(i);
        if (key && (key.includes('cloudkit') || key.includes('CloudKit'))) {
          keysToRemove.push(key);
        }
      }
      keysToRemove.forEach(key => localStorage.removeItem(key));
      // SessionStorageからも削除
      const sessionKeysToRemove = [];
      for (let i = 0; i < sessionStorage.length; i++) {
        const key = sessionStorage.key(i);
        if (key && (key.includes('cloudkit') || key.includes('CloudKit'))) {
          sessionKeysToRemove.push(key);
        }
      }
      sessionKeysToRemove.forEach(key => sessionStorage.removeItem(key));
      console.log('古い認証情報を削除しました');
    } catch (cleanupError) {
      console.warn('認証情報のクリーンアップ中にエラー:', cleanupError);
    }
    try {
      const cloudKit = window.CloudKit.configure({
        containers: [
          {
            containerIdentifier: 'XXXXXX',
            apiTokenAuth: {
              apiToken: 'XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX',
              persist: false,
              signInButton: {
                id: 'cloudkit-sign-in-button',
                theme: 'black',
              },
              signOutButton: {
                id: 'cloudkit-sign-out-button',
                theme: 'black',
              },
            },
            environment: 'development',
          },
        ],
      });
      console.info('⭐️ cloudKit', cloudKit);
      setCloudKitConfigured(true);
      const container = cloudKit.getDefaultContainer();
      console.info('⭐️ CloudKit configured, setting up auth...');
      // 初期認証状態をチェック
      try {
        const initialUser = await container.setUpAuth();
        console.info('⭐️ setUpAuth result:', initialUser);
      } catch (authError) {
        console.info('⭐️ setUpAuth error (expected for unauthenticated):', authError);
      }
      // CloudKitの標準コールバックも併用(念のため)
      try {
        container.whenUserSignsIn().then((userInfo: any) => {
          console.info('⭐️ CALLBACK: whenUserSignsIn fired!', userInfo);
        });
        container.whenUserSignsOut().then(() => {
          console.info('⭐️ CALLBACK: whenUserSignsOut fired!');
        });
      } catch (callbackError) {
        console.info('⭐️ Callback setup error (non-critical):', callbackError);
      }
      console.info('⭐️ initializeCloudKit - completed');
    } catch (error) {
      console.error('⭐️ Critical CloudKit initialization error:', error);
    }
  };
  return (
    <>
      <Script
        src="https://cdn.apple-cloudkit.com/ck/2/cloudkit.js"
        strategy="afterInteractive"
        onLoad={() => {
          initializeCloudKit();
        }}
        onError={error => {
          console.error('⭐️ CloudKit initialization error:', error);
        }}
      />
      <div id="cloudkit-sign-in-button" />
      <div id="cloudkit-sign-out-button" />
    </>
  );
}
In Chrome secret tab, I can sign in successfully.
But in Chrome normal tab, I can't sign in.
In normal tab, following error occurs on sign in button click:
cloudkit.js:14 Uncaught (in promise) Error: UNKNOWN_ERROR
cloudkit.js:14  GET https://api.apple-cloudkit.com/database/1/XXXXXX/XXXXXX/public/users/caller?ckjsBuildVersion=2420ProjectDev22&ckjsVersion=2.6.4&clientId=XXXXX-XXXXXXX-XXXX-XXXXX&
ckAPIToken=XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX 
421 (Misdirected Request)
I think, cloudkit instance has re-initialized when I click the sign in button only in normal tab.
So I can't sign in.
Do you have any idea what might be causing the error ?
Thanks in advance for your help!
                    
                  
                
                    
                      I’m trying to build a CRUD app using SwiftData,  @Query model and multidatepicker.
The data from a multidatepicker is stored or persists in SwiftData as Set = [].
My current dilemma is how to use SwiftData and @Query model Predicate to find all records on the current date.
I can’t find any SwiftData documentation or examples @Query using Set = [].
My CRUD app should retrieve all records for the current date.  Unfortunately, I don’t know the correct @Query model syntax for Set = [].
                    
                  
                
                    
                      Greetings i have an app that uses three different SwiftData models and i want to know what is the best way to use the them accross the app. I though a centralized behaviour and i want to know if it a correct approach.First let's suppose that the first view of the app will load the three models using the @Enviroment that work with @Observation. Then to other views that add data to the swiftModels again with the @Environment. Another View that will use the swiftData models with graph and datas for average and min and max.Is this a corrent way? or i should use @Query in every view that i want and ModelContext when i add the data.
@Observable
class CentralizedDataModels {
var firstDataModel: [FirstDataModel] = []
var secondDataModel: [SecondDataModel] = []
var thirdDataModel: [ThirdDataModel] = []
let context: ModelContext
init(context:ModelContext) {
self.context = context
}
}
                    
                  
                
                    
                      I'm continually getting an error with a new CloudKit container when I try to save data.
error: Couldn't get container configuration from the server for container "iCloud.com.***.***"
here's the class:
private var db = CKContainer(identifier: "iCloud.com.***.***").privateCloudDatabase
func addTask(taskItem: TaskItem) async throws {
    checkStatus()
    do {
        try await db.save(taskItem.record)
    } catch {
        print("error: \(error.localizedDescription)")
    }
}
func checkStatus()  {
    let id = CKContainer(identifier: "iCloud.com.***.***").containerIdentifier
    print(id ?? "unknown")
    Task {
        let status = try await CKContainer(identifier: "iCloud.com.***.***").accountStatus()
        switch status {
            case .available:
            print("available")
        case .noAccount:
            print("no account")
        case .restricted:
            print("restricted")
        case .couldNotDetermine:
            print("could not determine")
        case .temporarilyUnavailable:
            print("temporarily unavailable")
        @unknown default: break
        }
    }
}
The account status reports as available but gives the error on an attempt to save.. I'm trying to work out what I might be doing wrong..
                    
                  
                
                    
                      My client is using iCloud Mail with his custom domain and he communicated with many govt organizations which seem to all be using Barracuda Email Protection for their spam prevention. I have properly configured his SPF, DKIM & DMARC DNS records however his emails were still being rejected. (Email header below)
I contacted Barracuda support with the email header and they replied saying that the emails were rejected becuase Apple Mail has missing PTR records.
I have sent dozens of emails for testing and looking at all their headers I can see (ms-asmtp-me-k8s.p00.prod.me.com [17.57.154.37]) which does not have a PTR record.
----FULL EMAIL HEADER WITH 3RD PARTY DOMAINS REMOVED-----
<recipient_email_address>: host
d329469a.ess.barracudanetworks.com[209.222.82.255] said: 550 permanent
failure for one or more recipients (recipient_email_address:blocked)
(in reply to end of DATA command)
Reporting-MTA: dns; p00-icloudmta-asmtp-us-west-3a-100-percent-10.p00-icloudmta-asmtp-vip.icloud-mail-production.svc.kube.us-west-3a.k8s.cloud.apple.com
X-Postfix-Queue-ID: 8979C18013F8
X-Postfix-Sender: rfc822; sender_email_address
Arrival-Date: Thu, 20 Mar 2025 12:30:05 +0000 (UTC)
Final-Recipient: rfc822; @******
Original-Recipient: rfc822;recipient_email_address
Action: failed
Status: 5.0.0
Remote-MTA: dns; d329469a.ess.barracudanetworks.com
Diagnostic-Code: smtp; 550 permanent failure for one or more recipients
(recipient_email_address:blocked)
Return-Path: <sender_email_address>
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sender_domain;
s=sig1; bh=CyUt/U7mIHwXB5OQctPjRH/OxLH7GsLR54JjGuRkj9Y=;
h=From:Message-Id:Content-Type:Mime-Version:Subject:Date:To:x-icloud-hme;
b=hwEbggsctiCRlMlEgovBTjB/0sPRCb2k+1wzHRZ2dZNrZdOqvFSNWU+Aki9Bl8nfv
eEOoXz5qWxO2b2rEBl08lmRQ3hCyroayIn4keBRrgkxL1uu4zMTaDUHyau2vVnzC3h
ZmwQtQxiu7QvTS/Sp8jjJ/niOPSzlfhphqMxnQAZi/jmJGcZPadT8K+7+PhRllVnI+
TElJarN1ORQu+CaPGhEs9/F7AIcjJNemnVg1cude7EUuO9va8ou49oFExWTLt7YSMl
s+88hxxGu3GugD3eBnitzVo7s7/O9qkIbDUjk3w04/p/VOJ+35Mvi+v/zB9brpYwC1
B4dZP+AhwJDYA==
Received: from smtpclient.apple (ms-asmtp-me-k8s.p00.prod.me.com [17.57.154.37])
by p00-icloudmta-asmtp-us-west-3a-100-percent-10.p00-icloudmta-asmtp-vip.icloud-mail-production.svc.kube.us-west-3a.k8s.cloud.apple.com (Postfix) with ESMTPSA id 8979C18013F8;
Thu, 20 Mar 2025 12:30:05 +0000 (UTC)
From: Marcel Brunel <sender_email_address>
Message-Id: <2E8D69EA-FCA6-4F5D-9D42-22A955C073F6@sender_domain>
Content-Type: multipart/alternative;
boundary="Apple-Mail=_F9AC7D29-8520-4B25-9362-950CB20ADEC5"
Mime-Version: 1.0 (Mac OS X Mail 16.0 (3826.400.131.1.6))
Subject: Re: [EXTERNAL] - Re: Brunel - 2024 taxes
Date: Thu, 20 Mar 2025 07:29:27 -0500
In-Reply-To: <SA0PR18MB350300DE7274C018F66EEA24F2D82@SA0PR18MB3503_namprd18_prod_outlook_com>
To: Troy Womack <recipient_email_address>
References: <SA0PR18MB350314D0B88E283C5C8E1BB6F2DE2@SA0PR18MB3503_namprd18_prod_outlook_com>
<9B337A3E-D373-48C5-816F-C1884BDA6F42@sender_domain>
<SA0PR18MB350341A7172E8632D018A910F2D82@SA0PR18MB3503_namprd18_prod_outlook_com>
<SA0PR18MB350300DE7274C018F66EEA24F2D82@SA0PR18MB3503_namprd18_prod_outlook_com>
X-Mailer: Apple Mail (2.3826.400.131.1.6)
X-Proofpoint-ORIG-GUID: uqebp2OIbPqBr3dYsAxdFVkCNbM5Cxyl
X-Proofpoint-GUID: uqebp2OIbPqBr3dYsAxdFVkCNbM5Cxyl
X-Proofpoint-Virus-Version: vendor=baseguard
engine=ICAP:2.0.293,Aquarius:18.0.1093,Hydra:6.0.680,FMLib:17.12.68.34
definitions=2025-03-20_03,2025-03-19_01,2024-11-22_01
X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 clxscore=1030
suspectscore=0 mlxlogscore=999 mlxscore=0 phishscore=0 malwarescore=0
spamscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1
engine=8.19.0-2411120000 definitions=main-2503200077
                    
                  
                
              
                
              
              
                
                Topic:
                  
	
		App & System Services
  	
                
                
                SubTopic:
                  
                    
	
		iCloud & Data
		
  	
                  
                
              
              
              
  
  
    
    
  
  
              
                
                
              
            
          
                    
                      Hello everyone,
I am experiencing a persistent authentication error when querying a custom user profile record, and the error message seems to be a red herring.
My Setup:
I have a custom CKRecord type called ColaboradorProfile.
When a new user signs up, I create this record and store their hashed password, salt, nickname, and a custom field called loginIdentifier (which is just their lowercase username).
In the CloudKit Dashboard, I have manually added an index for loginIdentifier and set it to Queryable and Searchable. I have deployed this schema to Production.
The Problem:
During login, I run an async function to find the user's profile using this indexed loginIdentifier.
Here is the relevant authentication code:
func autenticar() async {
    // ... setup code (isLoading, etc.)
    let lowercasedUsername = username.lowercased()
    // My predicate ONLY filters on 'loginIdentifier'
    let predicate = NSPredicate(format: "loginIdentifier == %@", lowercasedUsername)
    let query = CKQuery(recordType: "ColaboradorProfile", predicate: predicate)
    
    // I only need these specific keys
    let desiredKeys = ["password", "passwordSalt", "nickname", "isAdmin", "isSubAdmin", "username"]
    let database = CKContainer.default().publicCloudDatabase
    do {
        // This is the line that throws the error
        let result = try await database.records(matching: query, desiredKeys: desiredKeys, resultsLimit: 1)
        
        // ... (rest of the password verification logic)
    } catch {
        // The error always lands here
        logDebug("Error authenticating with CloudKit: \(error.localizedDescription)")
        await MainActor.run {
            self.errorMessage = "Connection Error: \(error.localizedDescription)"
            self.isLoading = false
            self.showAlert = true
        }
    }
}
The Error:
Even though my query predicate only references loginIdentifier, the catch block consistently reports this error:
Error authenticating with CloudKit: Field 'createdBy' is not marked queryable.
I know createdBy (the system creatorUserRecordID) is not queryable by default, but my query isn't touching that field. I already tried indexing createdBy just in case, but the error persists. It seems CloudKit cannot find or use my index for loginIdentifier and is incorrectly reporting a fallback error related to a system field.
Has anyone seen this behavior? Why would CloudKit report an error about createdBy when the query is explicitly on an indexed, custom field?
I'm new to Swift and I'm struggling quite a bit.
Thank you,
                    
                  
                
                    
                      Hey folks, I'm having an issue where iCloud sync is only working in the Development environment, not on Prod. I have deployed the schema to Prod through the CloudKit console, although I did it after the app went live on the AppStore. Even though the two schema are identical, iCloud sync just doesn't work on Prod.
Things I tried on the code side:
Initially I did the most basic SwiftData+CloudKit setup:
var modelContainer: ModelContainer {
    let schema = Schema([Book.self, Goal.self])
    let config = ModelConfiguration(isStoredInMemoryOnly: false, cloudKitDatabase: doesUserSyncToiCloud ? .automatic : .none)
    var container: ModelContainer
    do {
        container = try ModelContainer(for: schema, configurations: config)
    } catch {
        fatalError()
    }
    return container
}
var body: some Scene {
    WindowGroup {
        AnimatedSplashScreen {
            MainTabView()
        }
    }
    .modelContainer(modelContainer)
}
This is enough to make iCloud sync work at the Development level. Then when I noticed the issues on Prod I did some digging and found this on the Docs (https://developer.apple.com/documentation/swiftdata/syncing-model-data-across-a-persons-devices):
let config = ModelConfiguration()
do {
#if DEBUG
    // Use an autorelease pool to make sure Swift deallocates the persistent 
    // container before setting up the SwiftData stack.
    try autoreleasepool {
        let desc = NSPersistentStoreDescription(url: config.url)
        let opts = NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.com.example.Trips")
        desc.cloudKitContainerOptions = opts
        // Load the store synchronously so it completes before initializing the 
        // CloudKit schema.
        desc.shouldAddStoreAsynchronously = false
        if let mom = NSManagedObjectModel.makeManagedObjectModel(for: [Trip.self, Accommodation.self]) {
            let container = NSPersistentCloudKitContainer(name: "Trips", managedObjectModel: mom)
            container.persistentStoreDescriptions = [desc]
            container.loadPersistentStores {_, err in
                if let err {
                    fatalError(err.localizedDescription)
                }
            }
            // Initialize the CloudKit schema after the store finishes loading.
            try container.initializeCloudKitSchema()
            // Remove and unload the store from the persistent container.
            if let store = container.persistentStoreCoordinator.persistentStores.first {
                try container.persistentStoreCoordinator.remove(store)
            }
        }
    }
#endif
    modelContainer = try ModelContainer(for: Trip.self, Accommodation.self,
                                        configurations: config)
} catch {
    fatalError(error.localizedDescription)
}
I've no idea why Apple would include this CoreData setup in a SwiftData documentation, but I went ahead and adapted it to my code as well. I see now that some new "assets" were added to my Development schema, but I'm afraid to deploy these changes to Prod, since I'm not even confident that this CoreData setup is necessary in a SwiftData app.
Does anyone have any thoughts on this? Have you run into similar issues? Any help would be much appreciated; thanks!
                    
                  
                
                    
                      I have developed an podcast app, where subscriped podcast & episodes synched with iCloud.
So its working fine with iOS & iPad with latest os version, but iCloud not synching in iPod with version 15.
Please help me to fix this.
Thanks
Devendra K.
                    
                  
                
                    
                      I want to clear all the data in the zone, but I can't delete it. Below is my code, no logs are printed when running.
static func clearData() {
        let coordinator = shared.container.persistentStoreCoordinator
        
        let fm = FileManager.default
        for d in shared.container.persistentStoreDescriptions {
            guard let url = d.url else { continue }
            do {
                if fm.fileExists(atPath: url.path()) {
                    try coordinator.destroyPersistentStore(at: url, type: .sqlite)
                }
            } catch {
                logger.debug("Failed to delete db file, \(error)")
            }
        }
        
        for description in shared.container.persistentStoreDescriptions {
            guard let originalStoreURL = description.url else { continue }
            let walFileURL = originalStoreURL.deletingPathExtension().appendingPathExtension("sqlite-wal")
            let shmFileURL = originalStoreURL.deletingPathExtension().appendingPathExtension("sqlite-shm")
            
            for url in [originalStoreURL, walFileURL, shmFileURL] {
                do {
                    if fm.fileExists(atPath: url.path()) {
                        try fm.removeItem(at: url)
                    }
                } catch {
                    logger.debug("Failed to delete db file, \(error)")
                }
            }
        }
        
        let container = CKContainer(identifier:  appContainerID)
        container.privateCloudDatabase.fetchAllRecordZones { zones, error in
            if let error = error {
                print("Error fetching zones: ")
            } else if let zone = zones?.first, zone.zoneID.zoneName == "_defaultZone" {
                PersistenceController.shared.container.purgeObjectsAndRecordsInZone(with: zone.zoneID, in: nil) { ckShare, error in
                    if let error = error {
                        print("Error purge zones: \(error)")
                    }
                    if ckShare == nil {
                        print("ckShare is nil")
                    }
                }
            }
        }
    }
                    
                  
                
                    
                      I've developed an app that allow me to send messages to all users by entering a record in Public database. On each users device, the app takes that Public record and creates a record in their Private database to track the Read and Deleted status.
It works flawlessly on the simulator and about 1/3 of the devices enrolled in my TestFlight. The other 2/3 are unable to write to their Private database. In fact, the CKContainer.default().privateCloudDatabase.save() operation causes the app to crash if I let it run.
I've looked at every Google link and I just can't figure out why this works for 1/3 of the users, but not the other 2/3. Incidentally, the 2/3 of the group that can't save to their Private database are also unable to save their Notification Subscription.
All devices are running iOS 18.0 or better iPhone 11 through 16 in testing pool. Each portion of the working/not working group are a mix of iPhone versions.
if !found && checkIcloudStatus() {
                CKContainer.default().privateCloudDatabase.save(loadPrivateData(n: processedMessages[index].recordName)) { returnedRecord, returnedError in
                    print("Adding new message to Private and error is: \(String(describing: returnedError))")
                    DispatchQueue.main.async {
                        self.processedMessages[index].record = returnedRecord ?? CKRecord(recordType: "messages_private")
                        self.processedMessages[index].unRead = true
                        self.processedMessages[index].deleted = false
                    }
                }
            }
func loadPrivateData(n: String) -> CKRecord {
        let record = CKRecord(recordType: "messages_private")
        record["deleted"] = "false"
        record["messageId"] = n
        record["unRead"] = "true"
        return record
    }
                    
                  
                
                    
                      Hi all,
I am using SwiftData and cloudkit and I am having an extremely persistent bug.
I am building an education section on a app that's populated with lessons via a local JSON file. I don't need this lesson data to sync to cloudkit as the lessons are static, just need them imported into swiftdata so I've tried to use the modelcontainer like this:
    static func createSharedModelContainer() -> ModelContainer {
         // --- Define Model Groups ---
        let localOnlyModels: [any PersistentModel.Type] = [
            Lesson.self, MiniLesson.self,
            Quiz.self, Question.self
        ]
        let cloudKitSyncModels: [any PersistentModel.Type] = [
            User.self, DailyTip.self, UserSubscription.self,
            UserEducationProgress.self // User progress syncs
        ]
However, what happens is that I still get Lesson and MiniLesson record types on cloudkit and for some reason as well, whenever I update the data models or delete and reinstall the app on simulator, the lessons duplicate (what seems to happen is that a set of lessons comes from the JSON file as it should), and then 1-2 seconds later, an older set of lessons gets synced from cloudkit.
I can delete the old set of lessons if I just delete the lessons and mini lessons record types, but if I update the data model again, this error reccurrs.
Sorry, I don't know if I managed to explain this well but essentially I just want to stop the lessons and minilessons from being uploaded to cloudkit as I think this will fix the problem. Am I doing something wrong with the code?
                    
                  
                
                    
                      Hi !
Would anyone know (if possible) how to create backup files to export and then import from the data recorded by SwiftData?
For those who wish, here is a more detailed explanation of my case:
I am developing a small management software with customers and events represented by distinct classes. I would like to have an "Export" button to create a file with all the instances of these 2 classes and another "Import" button to replace all the old data with the new ones from a previously exported file.
I looked for several solutions but I'm a little lost...