I've found old forum posts that reference CloudKit pricing based on usage (after exceeding the 'Free' tier). However, it doesn't seem that Apple has any information on any of their website that indicate what that pricing is, or otherwise the limits of a free tier.
The closest I've found to this is on https://developer.apple.com/icloud/cloudkit/ where it says, "Store private data securely in your users’ iCloud accounts for limitless scale as your user base grows, and get up to 1PB of storage for your app’s public data."
So does this mean that the only CloudKit limits now are:
Private data: dependent on individual user's remaining iCloud storage space
Public data: 1 PB
Request count/day: unlimited
Download usage/day: unlimited
I'm being a little sarcastic, but at the same time, if there are still limits and a pricing structure, I'm really scratching my head as to why that doesn't seem to be published anywhere.
Ultimately, I'm trying to find the best, reliable public asset storage with cross-device usage (iOS, tvOS) solution and am weighing CloudKit versus other cloud storage solutions and their costs.
Side note: I'm kinda confused why CloudKit provides public asset storage in the first place, since I thought On-Demand Resources was intended to fill that gap (and ODR does have storage limits too).
iCloud & Data
RSS for tagLearn how to integrate your app with iCloud and data frameworks for effective data storage
Post
Replies
Boosts
Views
Activity
I have a CoreData model, in a Swift Package with tests.
I can successfully run the tests, when I load the model using NSPersistentContainer, however attempting this with NSPersistentCloudKitContainer always fails in the call to loadPersistentStores(completionHandler block: @escaping (NSPersistentStoreDescription, Error?) -> Void)
The error is : [CK] BUG IN CLIENT OF CLOUDKIT: Not entitled to listen to push notifications. Please add the 'aps-connection-initiate' entitlement.
This issue is described on StackOverflow however, the accepted solution does not appear to work in my case.
I have tried adding the aps-connection-initiate key to my App Info.plist, the Test Info.plist and the SPM bundle. No change. (NB. adding this to the entitlements file just breaks auto signing).
I have enabled App entitlements for App Groups, Remote Notifications background mode, Push Notifications and iCloud CloudKit with a store identifier.
I have checked my model. All relationships have inverses. No unique constraints, etc. etc.
I am sharing a Bundle ID with a previous version of the App, that also uses CoreData+CloudKit, each version has it's own Model and container identifier, each container identifier is available in the provisioning profile.
The new version of the model has two NSPersistentStoreDescriptions, one is configured for CloudKit, the other is a local cache.
I am completely stuck, suggestions would be very welcome.
#1 As a new starter, I just created a new sample app in Xcode and added iCloud capability. On the CloudKit dashboard I do see the container but selecting the specific container shows the following message in red "Error loading container details."
#2 I was able to create a new RecortType via the cloud kit dashboard UI but when I try to create a record form the dashboard UI somehow it does not let me select the record type of the record (I see it in the list but its grayed out).
I am not sure what the reason for #1 and #2 and if the two issues are related. Could not find any help online. I am trying to create an app directly with cloudKit and Javascript (not a companion IOS app). Any help would
Hi, I have found another bug if I'm not mistaken in core data.
When we are using a derived attribute in our xcdatamodel file after making the mapping file there is an error:
Can't find mapping model for migration
If you are looking to reproduce the bug I made a super simple example app at my branch in the link below:
https://github.com/hamed8080/LeitnerBox/tree/fix_migration
Keep that in mind if I remove the derived attribute and afterward make a migration with a new mapping file, it works correctly!
CKRecord is a class which does not conform to the Sendable protocol. Its fields consist of NSStrings, NSData and others which are not Sendable. I understand that Apple is incrementally modifying objects to be sendable, but I am experiencing and I would assume others are experiencing a very large number of warnings (for now) about CKRecords and Sendable.
It may be too much to make CKRecord Sendable and it may be too much to create a Sendable version of CKRecord, but it would be nice if it could at least be investigated.
My particular situation is I have created a Protocol named CKMethods which some of my view controllers use to download and upload CKRecords. I suddenly have a large number of warnings about non-sendable types being sent from main actor-isolated context to non-isolated instance method. The CKRecords sent to and from the protocol do not get mutated and I have never had a problem with data races in the years that I have had this protocol. At some point, the warnings will probably become errors and I definitely do not want to get to that point.
I am still coming up to speed on Swift Concurrency, so there may be a more simple solution than the one I am working on - creating a Sendable Struct for every CKRecord type that I have in my app and modifying all of the methods to pass the Struct instead of a CKRecord and convert the Struct to a CKRecord for upload and convert the CKRecord to the Struct for download.
I’m using NSPersistentCloudKitContainer and I’m utilising the public database and also the user’s private database.
For example I have an entity called Category which has a many-to-many relationship to an entity called NewsArticle. So the NewsArticles exist in the public database for the user to browse, but he can add them to a category which will live in his private database. So that’s my question, is it possible for an entity which exists a in the private database to have a relationship to another entity in a public database?
Is SwiftData going to be immediately available to use with iOS 16? I ask because I'm working on an app which I'd like to release around the end of this month, and I'm about to implement CoreData for it, but wanted to see when SwiftData would be available. My guess was that SwiftData is for iOS 17 so I should just stick with CoreData for now and switch over later, but just wanted to check to make sure. Thanks!
I did manage to save my Entities to CloudKit with SwiftData but the default database is the private database. I need to store some Entities in the private and other Entities in the public CloudKit database. How do I manage that with SwiftData? With CoreData I always used different configurations for both private and public and added the entities to one or the other.
Hi,
re: the SwiftData session "Create an app with SwifData" (https://developer.apple.com/videos/play/wwdc2023/10154)
I noted the mention of generating sample preview data. In CoreData, I had a similar need and this was achieved by creating a shared in-memory context; fairly straight forward.
The example given for SwiftData was decorated with @MainActor and then added to the target project, then in the #Preview closure, the modelContainer is amended to point to the preview data. Anyways, my problem is that I'm receiving an error when trying to render the preview in question:
main actor-isolated let 'previewContainer' can not be referenced from a non-isolated context
I suppose my issue is not having used the MainActor wrapper before and being unclear on what's possibly going wrong here (or if it's not just a "me" problem).
Can anyone help?
How does SwiftData work with background operations? CoreData had background context that could be used to avoid UI hang for heavy operations.
Is there an equivalent in SwiftData, and if so, do I have to merge changes or does it save directly to persistent store?
Using the 'Create SwiftData Code...' action in Xcode results in Model that have bi-directional relationships between many of my entities (which is correct - my Core Data model includes this).
All of these Relationships are marked as invalid, however, with the following error:
Circular reference resolving attached macro 'Relationship'
Most ORM's, in my experience, have a way to mark one end of a bidirectional relationship as an 'owner'. Is there something similar available in SwiftData, or is this scenario handled in a different way? Or am I going to need to remove all of my bidirectional relationships?
If I make model changes in the mainContext using a batch operation like context.update OR on a background thread ModelContext ModelContext(container), my saved changes are not automatically reflected in the UI (a List of models).
Also ModelContext.willSave and ModelContext.didSave don't seem to get called.
Will automatic UI updates work in an upcoming Beta but are NOT in Beta 1?
Or will we refresh View/@Query based on a ModelContext.didSavenotification?
Or should this be working in Beta 1 and I am missing how it works?
Is there a way to use SwiftData without automatic iCloud sync? I’d like to do that manually using my own CloudKit solution or CKSyncEngine. SwiftData automatically picks up any CloudKit containers though and I have not seen an option to disable this behavior. Setting cloudKitContainerIdentifier to nil does still pick the first available CloudKit container.
Just in case this is a bug: FB12276416
Sample:
let configuration = ModelConfiguration(cloudKitContainerIdentifier: nil)
let modelContainer = try! ModelContainer(for: [GamesCollection.self], configuration)
print(modelContainer.configurations)
// [SwiftData.ModelConfiguration(url: …, name: …, sharedAppContainerIdentifier: …, cloudKitContainerIdentifier: Optional("iCloud.CloudKit.com.+++")
Just for grins, I tried running the SwiftData generation tool on the existing Core Data model of a non-trivial app I've worked on for a decade or so. It's pretty substantial, and uses some more advanced features, so it seemed like an interesting test case.
One of the warnings that was not reported by the UI, but which showed up in the generated code was quite a few instances of this:
Entity inheritance on entity Bar (parent class Foo) is unsupported in SwiftData.
Now that I'm looking at the code examples more carefully, I see an awful lot of final class, which maybe should have raised a red flag sooner. But to the best of my recollection, none of the sessions outright said that inheritance (was or) was not supported. Core Data has supported this functionality for a long time (maybe since the beginning).
Assuming that this isn't supported in this first seed, are there plans to provide this functionality in the future? By the launch of iOS 17?
(For the record, this model has 93 entities, of which 34 have parent entities. 14 are abstract, which I gather is also not supported. 3 of the entities are both abstract and have parent entities.)
Hi,
in the session the following is mentioned:
If a trip already exists with that name, then the persistent back end will update to the latest values. This is called an upsert. An upsert starts as an insert. If the insert collides with existing data, it becomes an update and updates the properties of the existing data.
Nevertheless, if I have a unique constraint on an (String) attribute and try to insert the same again, I end up in the debugger in the generated getter of the attribute:
@Attribute(.unique) public var name: String
{
get {
_$observationRegistrar.access(self, keyPath: \.name)
return self.getValue(for: \.name) // <- here
}
EXC_BREAKPOINT (code=1, subcode=0x1a8d6b724)
Am I missing something? If this is expected behaviour, how should I prevent this crash (other than checking for uniqueness before every insert)?
Thank you!
Cheers, Michael
Did anyone successfully used transformable in SwiftData to store UIColor or SwiftUI Color type?
@Attribute(.transformable) var color: UIColor
Hey,
I am trying to save an enum in my model with SwiftData but getting a weird error message I do not understand at the moment, and I am pretty sure I am missing something here.
public enum URLScheme: String, Codable {
case https
case http
}
@Model
public class MyModel {
public var urlScheme: URLScheme
}
When I try to save the model I get the following error message in the console:
error: Row (pk = 1) for entity 'MyModel' is missing mandatory text data for property 'https'
I was wondering if I need to tell SwiftData how to save my enum ? My assumption was that I can save any enum if it conforms to Codable. Am I doing something wrong here or is this a beta bug ?
Thanks a lot for helping
I may not be understanding this right, but when trying to use the new @Environment for what was previously @EnvironmentObject I am unable to use a NavigationPath in a NavigationStack:
@Observable
class AppData {
var presented: NavigationPath = NavigationPath()
}
NavigationStack(path: appData.$presented) {...
Value of type 'AppData' has no member '$presented'
Cannot convert value of type 'NavigationPath' to expected argument type 'Binding'
Moving the $ to the front or removing it does nothing either.
In the "old" world we could define a model property as an integer (e.g. "Integer 64") and then have the actual class representing that model define the property as an enum instead and have getters/setters using methods such as primitiveValue(forKey:)
When migrating to use SwiftData I changed the model to be an actual enum type and even though the underlying type of the enum is an integer and therefore supported by the primitive storage it requires me to use Codable on the enum instead and doing so makes it incompatible with the old CoreData model.
Does anyone have any ideas or workarounds here or do you feel it is a bug and should be reported?
enum FooType: Int64 {
case awesome
case super
}
@Model
final class Note {
var type: FooType // ERROR
}
How do I delete all the rows in an entity and/or delete the entity all together in SwiftData?
Here is a function I used to delete an entity in core data for reference.
class func deleteEntity(entity: String) {
let fetchRequest1: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: entity)//entity.fetchRequest()
let batchDeleteRequest1 = NSBatchDeleteRequest(fetchRequest: fetchRequest1)
_ = try? PersistanceController.shared.container.viewContext.execute(batchDeleteRequest1)
print("Deleting coredata entity: \(entity)")
}