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
About 4 months ago, I shipped the first version of my app with 4 versioned schemas that, unintentionally, had the same versionIdentifier of 1.2.0 in 2 of them:
V1: 1.0.0
V2: 1.1.0
V3: 1.2.0
V4: 1.2.0
They are ordered correctly in the MigrationPlan, and they are all lightweight.
Migration works, SwiftData doesn't crash on init and I haven't encountered any issues related to this. The app syncs with iCloud.
Questions, preferable for anybody with knowledge of SwiftData internals:
What will break in SwiftData when there are 2 duplicate numbers?
Not that I would expect it to be safe, but does it happen to be safe to ship an update that changes V4's version to 1.3.0, what was originally intended?
Topic:
App & System Services
SubTopic:
iCloud & Data
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 = [].
Hey everyone, I have a question. When creating an app, how should I design a message table that involves personal privacy? The content is stored locally on the user's device, and then encrypted in the server database? How should I design it?
Topic:
App & System Services
SubTopic:
iCloud & Data
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 have a document based SwiftData app in which I would like to implement a persistent cache. For obvious reasons, I would not like to store the contents of the cache in the documents themselves, but in my app's data directory.
Is a use case, in which a document based SwiftData app uses not only the ModelContainers from the currently open files, but also a ModelContainer writing a database file in the app's documents directory (for cache, settings, etc.) supported?
If yes, how can you inject two different ModelContexts, one tied to the currently open file and one tied to the local database, into a SwiftUI view?
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
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
}
}
In a document based SwiftData app for macOS, how do you go about opening a (modal) child window connected to the ModelContainer of the currently open document?
Using .sheet() does not really result in a good UX, as the appearing view lacks the standard window toolbar.
Using a separate WindowGroup with an argument would achieve the desired UX. However, as WindowGroup arguments need to be Hashable and Codable, there is no way to pass a ModelContainer or a ModelContext there:
WindowGroup(id: "myWindowGroup", for: MyWindowGroupArguments.self) { $args in
ViewThatOpensInAWindow(args: args)
}
Is there any other way?
The stuff I've found by searching has confused me, so hopefully someone can help simplify it for me?
I have an app (I use it for logging which books I've given away), and I could either add a bunch of things to the app, or I could have another app (possibly a CLI tool) to generate some reports I'd like.
I'm trying to build a custom FetchRequest that I can use outside a View. I've built the following ObservableFetchRequest class based on this article: https://augmentedcode.io/2023/04/03/nsfetchedresultscontroller-wrapper-for-swiftui-view-models
@Observable @MainActor class ObservableFetchRequest<Result: Storable>: NSObject, @preconcurrency NSFetchedResultsControllerDelegate {
private let controller: NSFetchedResultsController<Result.E>
private var results: [Result] = []
init(context: NSManagedObjectContext = .default, predicate: NSPredicate? = Result.E.defaultPredicate(), sortDescriptors: [NSSortDescriptor] = Result.E.sortDescripors) {
guard let request = Result.E.fetchRequest() as? NSFetchRequest<Result.E> else {
fatalError("Failed to create fetch request for \(Result.self)")
}
request.predicate = predicate
request.sortDescriptors = sortDescriptors
controller = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
super.init()
controller.delegate = self
fetch()
}
private func fetch() {
do {
try controller.performFetch()
refresh()
}
catch {
fatalError("Failed to fetch results for \(Result.self)")
}
}
private func refresh() {
results = controller.fetchedObjects?.map { Result($0) } ?? []
}
var predicate: NSPredicate? {
get {
controller.fetchRequest.predicate
}
set {
controller.fetchRequest.predicate = newValue
fetch()
}
}
var sortDescriptors: [NSSortDescriptor] {
get {
controller.fetchRequest.sortDescriptors ?? []
}
set {
controller.fetchRequest.sortDescriptors = newValue.isEmpty ? nil : newValue
fetch()
}
}
internal func controllerDidChangeContent(_ controller: NSFetchedResultsController<any NSFetchRequestResult>) {
refresh()
}
}
Till this point, everything works fine.
Then, I conformed my class to RandomAccessCollection, so I could use in a ForEach loop without having to access the results property.
extension ObservableFetchRequest: @preconcurrency RandomAccessCollection, @preconcurrency MutableCollection {
subscript(position: Index) -> Result {
get {
results[position]
}
set {
results[position] = newValue
}
}
public var endIndex: Index { results.endIndex }
public var indices: Indices { results.indices }
public var startIndex: Index { results.startIndex }
public func distance(from start: Index, to end: Index) -> Int {
results.distance(from: start, to: end)
}
public func index(_ i: Index, offsetBy distance: Int) -> Index {
results.index(i, offsetBy: distance)
}
public func index(_ i: Index, offsetBy distance: Int, limitedBy limit: Index) -> Index? {
results.index(i, offsetBy: distance, limitedBy: limit)
}
public func index(after i: Index) -> Index {
results.index(after: i)
}
public func index(before i: Index) -> Index {
results.index(before: i)
}
public typealias Element = Result
public typealias Index = Int
}
The issue is, when I update the ObservableFetchRequest predicate while searching, it causes a Index out of range error in the Collection subscript because the ForEach loop (or a List loop) access a old version of the array when the item property is optional.
List(request, selection: $selection) { item in
VStack(alignment: .leading) {
Text(item.content)
if let information = item.information { // here's the issue, if I leave this out, everything works
Text(information)
.font(.callout)
.foregroundStyle(.secondary)
}
}
.tag(item.id)
.contextMenu {
if Item.self is Client.Type {
Button("Editar") {
openWindow(ClientView(client: item as! Client), id: item.id!)
}
}
}
}
Is it some RandomAccessCollection issue or a SwiftUI bug?
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...
I have a CoreData model with two configuration - but several problems. Notably the viewContext only shows data from the .private configuration. Here is the setup:
The private configuration holds entities, for example, User and Course and the shared one holds entities, for example, Player and League. I setup the NSPersistentStoreDescriptions to use the same container but with a databaseScope of .private/.shared and with the configuration of "Private"/"Shared". loadPersistentStores() does not report an error.
If I try container.initializeCloudKitSchema() only the .private configuration produces CKRecord types. If I create a companion app using one configuration (w/ all entities) the schema initialization creates all CKRecord types AND I can populate some data in the .private and a created CKShare. I see that data in the CloudKit dashboard.
If I axe the companion app and run the real thing w/ two configurations, the viewContext only has the .private data. Why?
If when querying history I use NSPersistentHistoryTransaction.fetchRequest I get a nil return when using two configurations (but non-nil when using one).
Hi,
I’m completely stuck with a very strange CloudKit problem that started recently and has now killed all iCloud sync for a live production app.
What is happening
Production container: iCloud.gainzCloud (created ~11 months ago, has been working perfectly until now)
In Xcode 26.0 (17A321):
→ Signing & Capabilities → iCloud is enabled
→ Container correctly shows as iCloud.gainzCloud
→ App builds and runs on device/simulator with zero provisioning or container errors
CloudKit Dashboard (https://icloud.developer.apple.com/dashboard/): completely blank – “No containers found”
Result: CloudKit sync is dead for every user (development + production environments)
What I know for sure
Apple Developer Support confirmed the container iCloud.gainzCloud still exists and is correctly attached to my Team ID on their backend
Personal iCloud (Mail, Notes, Photos, etc.) syncs perfectly on the same Mac / same Apple ID under macOS Tahoe 26.1
I have NOT changed the password on either the Apple ID or the Developer Program account
New containers I create appear in Xcode but never show up in the Dashboard
Environment
macOS Tahoe 26.1 (latest)
Xcode Version 26.0 (17A321)
Has anyone on the new Tahoe/Xcode 26 releases seen the CloudKit Dashboard suddenly go completely empty while Xcode still “sees” the container just fine?
Any known trick to force the dashboard to re-index containers or clear whatever cache is broken?
Thanks a lot in advance – this is blocking all iCloud functionality for a released app with active users.
Topic:
App & System Services
SubTopic:
iCloud & Data
We have an unreleased SwiftData app for iOS18+. While we were testing I saw reports on the forum about unexpected database migrations for codable arrays on iOS26.1.
I'd like to ask a couple of questions:
1- Does this issue originate from the new Xcode version, or is it specific to iOS 26.1?
2- Is it possible to change our attribute so that users on older iOS versions receive the same model, preventing a migration from being triggered when they upgrade to iOS 26.1?
One of our models looks like this:
struct Point: Codable, Hashable {
let x: Int
let y: Int
}
@Model
class Grid {
private(set) var gridId: String = ""
var points: [Point] = []
var updatedAt: Date = Date()
private(set) var createdAt: Date = Date()
#Index<Grid>([\.gridId])
...
}
I can think of some options like:
// 1
@Attribute(.transformable(by: CustomJsonTransformer.self)) var points: [Point] = []
// 2
@Attribute(.externalStorage) var points: [Point] = []
// 3
var points: Data = Data() // store points as data
However, I'm not sure which one to use.
What would you recommend to handle this, or is there a better strategy you would suggest?
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.
Hi all,
I recently discovered that I forgot to deploy my CloudKit schema changes from development to production - an oversight that unfortunately went unnoticed for 2.5 months.
As a result, any data created during that time was never synced to iCloud and remains only in the local CoreData store. Once I pushed the schema to production, CloudKit resumed syncing new changes as expected.
However, this leaves me with a gap: there's now a significant amount of data that would be lost if users delete or reinstall the app.
Before I attempt to implement a manual backup or migration strategy, I was wondering:
Does NSPersistentCloudKitContainer keep track of local changes that couldn't be synced doe to the missing schema and automatically reattempt syncing them now that the schema is live?
If not, what would be the best approach to ensure this "orphaned" data gets saved to CloudKit retroactively.
Thanks in advance for any guidance or suggestions.
We're in the process of migrating our app to the Swift 6 language mode. I have hit a road block that I cannot wrap my head around, and it concerns Core Data and how we work with NSManagedObject instances.
Greatly simplied, our Core Data stack looks like this:
class CoreDataStack {
private let persistentContainer: NSPersistentContainer
var viewContext: NSManagedObjectContext { persistentContainer.viewContext }
}
For accessing the database, we provide Controller classes such as e.g.
class PersonController {
private let coreDataStack: CoreDataStack
func fetchPerson(byName name: String) async throws -> Person? {
try await coreDataStack.viewContext.perform {
let fetchRequest = NSFetchRequest<Person>()
fetchRequest.predicate = NSPredicate(format: "name == %@", name)
return try fetchRequest.execute().first
}
}
}
Our view controllers use such controllers to fetch objects and populate their UI with it:
class MyViewController: UIViewController {
private let chatController: PersonController
private let ageLabel: UILabel
func populateAgeLabel(name: String) {
Task {
let person = try? await chatController.fetchPerson(byName: name)
ageLabel.text = "\(person?.age ?? 0)"
}
}
}
This works very well, and there are no concurrency problems since the managed objects are fetched from the view context and accessed only in the main thread.
When turning on Swift 6 language mode, however, the compiler complains about the line calling the controller method:
Non-sendable result type 'Person?' cannot be sent from nonisolated context in call to instance method 'fetchPerson(byName:)'
Ok, fair enough, NSManagedObject is not Sendable. No biggie, just add @MainActor to the controller method, so it can be called from view controllers which are also main actor. However, now the compiler shows the same error at the controller method calling viewContext.perform:
Non-sendable result type 'Person?' cannot be sent from nonisolated context in call to instance method 'perform(schedule:_:)'
And now I'm stumped. Does this mean NSManageObject instances cannot even be returned from calls to NSManagedObjectContext.perform? Ever? Even though in this case, @MainActor matches the context's actor isolation (since it's the view context)?
Of course, in this simple example the controller method could just return the age directly, and more complex scenarios could return Sendable data structures that are instantiated inside the perform closure. But is that really the only legal solution? That would mean a huge refactoring challenge for our app, since we use NSManageObject instances fetched from the view context everywhere. That's what the view context is for, right?
tl;dr: is it possible to return NSManagedObject instances fetched from the view context with Swift 6 strict concurrency enabled, and if so how?
Document based SwiftData apps do not autosave changes to the ModelContext at all. This issue has been around since the first release of this SwiftData feature.
In fact, the Apple WWDC sample project (https://developer.apple.com/documentation/swiftui/building-a-document-based-app-using-swiftdata) does not persist any data in its current state, unless one inserts modelContext.save() calls after every data change.
I have reported this under the feedback ID FB16503154, as it seemed to me that there is no feedback report about the fundamental issue yet.
Other posts related to this problem:
https://forums.developer.apple.com/forums/thread/757172
https://forums.developer.apple.com/forums/thread/768906
https://developer.apple.com/forums/thread/764189
We are currently implementing a custom iCloud sync for our macOS and iOS apps using CloudKit. Syncing works fine as long as the number of record sends is relatively small.
But when we test with a large number of changes ( 80,000+ CKRecords ) we start running into problems.
Our sending strategy is very conservative to avoid rate limits:
We send records sequentially in batches of 250 records
With about 2 seconds pause between operations
Records are small and contain no assets (assets are uploaded separately)
At some point we start receiving:
“Database commit size exceeds limit”
After that, CloudKit begins returning rate-limit errors with retryAfter-Information in the error.
We wait for the retry time and try again, but from this moment on, nothing progresses anymore. Every subsequent attempt fails.
We could not find anything in the official documentation regarding such a “commit size” limit or what triggers this failure state.
So my questions are:
Are there undocumented limits on the total number of records that can exist in an iCloud database (private or shared)?
Is there a maximum volume of record modifications a container can accept within a certain timeframe, even if operations are split into small batches with pauses?
Is it possible that sending large numbers of records in a row can temporarily or permanently “stall” a CloudKit container?
Any insights or experiences would be greatly appreciated.
Thank you!