iCloud & Data

RSS for tag

Learn how to integrate your app with iCloud and data frameworks for effective data storage

CloudKit Documentation

Post

Replies

Boosts

Views

Activity

SwiftData inside Actor leads to memory leaks
i am developing a SwiftUI App, where i need to work with relatively large amounts of data sets. While processing these data i had some issues with my app crashing randomly. As i was debugging this situation for a while i found out that dataraces were the cause for these crashes. That is why i decided to use an actor for these things.. As the actor takes care of concurrent threads, i was not having any crashes anymore, BUT, now i have to deal with some memory leaks! i've created a simple demo project to reproduce these leaks. my view: struct ContentView: View { @Environment(\.modelContext) private var modelContext // @Query private var items: [Item] var body: some View { VStack { Button(action: { Task { await testImport() } }, label: { Text("Import") }) } } } the function: func testImport() async { let actorX = testActor(container: self.modelContext.container) await actorX.cleanUp() // create dummy data: var dummyArray: [Int] = [] for i in 0...1300 { dummyArray.append(i) } await actorX.saveAssets(with: dummyArray) dummyArray = [] print("Checkpoint") } the actor: actor testActor { public var modelContainer: ModelContainer public var modelExecutor: any ModelExecutor private var context: ModelContext { modelExecutor.modelContext } public init(container: ModelContainer) { self.modelContainer = container let context = ModelContext(modelContainer) modelExecutor = DefaultSerialModelExecutor(modelContext: context) } func cleanUp() { print("starting cleanup...") do { try context.delete(model: Item.self) print("cleanup: table LocalAsset truncated") } catch { print("Failed to clear all LocalAsset data.") } } func saveAssets(with array: [Int]) { for i in 0..<array.count { let foo = array[i] let newItem = Item(timestamp: Date(), dummyInt: foo) context.insert(newItem) } try? context.save() } } And Here's a screenshot of Xcode's Instruments Leak tool: i hope somebody has any idea how to get rid of those leaks..
4
2
550
Mar ’24
API for new "Keep Downloaded" feature in iCloud Drive?
It looks like in iOS 18, there is a new option in Files to "Keep Downloaded". I.e., mark a file to be downloaded and never evicted. Is there an API that would allow us to provide this feature in our app? Our app stores files in a ubiquitous container and displays them in a custom UI (not a UIDocumentBrowserViewController). We've had a longstanding request from users that they be able to mark a file as always available locally, so that they can make sure they have access to it even if they go offline. We've done a hacky, best-effort implementation of this, but there is no truly reliable way to achieve this through the existing APIs.
1
0
186
Jun ’24
CloudKit in TestFlight: No sync between devices 😭
I have read and tried all the possible solutions available online, but still didn't get a result. My multi-platform iOS/macOS app uses private databases in iCloud with Core Data. All works as expected when I build the app from Xcode to my multiple devices: data is being synced. But when I upload the app to TestFlight, data is not being synced. This is what I have already tried: In CloudKit Dashboard, I reset the schema and deployed schema changes from the development to production. In Xcode project settings, in Targets, under Frameworks, Libraries... I added the CloudKit.framework, set as "do not embed". In Xcode project settings, under Signing & Capabilities, all the CloudKit, Background fetch and Remote notifications checkboxes are enabled for both Debug and Release. They all point to the same correct iCloud container. In Xcode project settings, under Build Settings, Code Signing Entitlements for both Debug and Release point to the same entitlements file. In .entitlements file, CloudKit container identifier points to the correct container. iCloud Services set to CloudKit. In .entitlements file, APS Environment for both iOS and macOS is set as "production". In Core Data .xcdatamodeld file, under Configurations, I have a Default option, and it is being set to "Used with CloudKit." Each time I upload new version to the TestFlight, I delete all the previous versions from all my devices, so development and production containers are not mixed up in any way. I understand that I may be missing something. But after researching all the resources available online, I didn't find anything else to configure or to add in this setup. I want to point out again that data is not being synced only in TestFlight, and thus, possibly, after release. Whenever I build app directly to the device from Xcode, all works as expected. I hope someone can help me.
2
0
229
Jun ’24
SwiftData Custom Datastore Docs and Implementation
I have watched the following WWDC 2024 sessions: What’s new in SwiftData Create a custom data store with SwiftData Platform State of the Union Now, I have an application that exposes a GraphQL API endpoint that's using PostgreSQL Server 16.3 database. Next, this API returns JSON to the client application (i.e. SwiftUI app). Furthermore, I have checked the current documentation and the above videos appear to be the best reference at this time. My proposed architecture looks like the following: SwiftUI <--> SwiftData <--> PostgreStoreConfiguration && PostgreStore TBD <--> GraphQL API <--> PostgreSQL Thus, I have the following questions: Are there plans to add common out-of-the-box data store implementations for PostgreSQL, Cassandra, Redis, and so on? Will it be possible to implement data stores built to use gRPC, GraphQL, REST, and others to name a few? Will there be more documentation on the actual creation of a custom data store because the current documentation provides a slim API reference? I look forward to your feedback regarding the SwiftData custom data stores.
1
0
317
Jun ’24
SwiftData SchemaMigrationPlan and VersionedSchema not Sendable?
I've just tried to update a project that uses SwiftData to Swift 6 using Xcode 16 beta 1, and it's not working due to missing Sendable conformance on a couple of types (MigrationStage and Schema.Version): struct LocationsMigrationPlan: SchemaMigrationPlan { static let schemas: [VersionedSchema.Type] = [LocationsVersionedSchema.self] static let stages: [MigrationStage] = [] } struct LocationsVersionedSchema: VersionedSchema { static let models: [any PersistentModel.Type] = [ Location.self ] static let versionIdentifier = Schema.Version(1, 0, 0) } This code results in the following errors: error: static property 'stages' is not concurrency-safe because non-'Sendable' type '[MigrationStage]' may have shared mutable state static let stages: [MigrationStage] = [] ^ error: static property 'versionIdentifier' is not concurrency-safe because non-'Sendable' type 'Schema.Version' may have shared mutable state static let versionIdentifier = Schema.Version(1, 0, 0) ^ Am I missing something, or is this a bug in the current seed? I've filed this as FB13862584.
1
2
327
Jun ’24
SwiftData won't work with Measurement types
I'm trying out SwiftData and converting my existing data models using Structs and Codable to Classes and SwiftData. I've got a model that has a Measurement<UnitMass> type. When I run the app after converting everything to use classes with the @Model macro, I get a fatal error: SwiftData/SchemaProperty.swift:325: Fatal error: Unexpected type for CompositeAttribute: NSUnitMass. Since Measurement conforms to Codable, and SwiftData should work with Codable types, why is this not working? I also tried marking the property with @Attribute(.transformable) and it didn't make a difference.
10
12
3.0k
Jun ’23
CloudKit Request - CKAsset size limit and public database storage per active user
Hello, I had a WWDC Lab with two CloudKit engineers who asked me to file a "Feedback Request" for critical information regarding CloudKit. I've filed the FB and have also decided to post a forum post to increase my chances of having these critical questions answered. If allowed, I will also post responses to my FB here. CKAssets I would like to know how large assets attached to a CKAsset can get before being rejected by the system. If the figure differs for private and public databases, please also let me know. CloudKit pricing information There used to be pricing information available on the website, but there's basically no information now. This makes it hard to calibrate user upload limits for my app in order to avoid overage fees. I'm not looking to game the system, (something this strange opaqueness is likely meant to prevent); I'm just looking to avoid a situation where competitors and vandals abuse my the content upload system so I get smacked by large bills out of nowhere. A rough figure of how many GB of data each active user adds to my app's CloudKit public database would suffice. While we're at it, if I have two apps that share a public database (if that's possible), do the active user counts of both contribute to the public database's free threshold?
0
0
177
Jun ’24
CloudKit sync refresh problem when change from iOS to macOS
I am trying to test CloudKit for sync, and am testing with the Xcode (15.4) SwiftUI templates (CoreData and SwiftData variants) and also with the CKSyncEngine sample-cloudkit-sync-engine example. I am then testing sync by running app in my MacBook and my iPhone. Generally sync is working, but the behavior is very different when syncing changes from macOS -> iOS compared to from iOS -> macOS: I open app on by my MacBook and iPhone I add item on my MacBook, it shows up a second later on iPhone On the other hand, if I add item on my iPhone it never shows up on my MacBook until I send app to background and then bring back to foreground. Is this known/expected behavior? Any way to fix? I assume this is a CKSyncEngine issue since the behavior is the same across all the different app setups and I think they all have CKSyncEngine in common. For the sample-cloudkit-sync-engine example I have also tried calling try await self.database.syncEngine.fetchChanges(.init(scope: .all)) on the mac, but that doesn't seem to help. I still need to put app into background and then bring back to foreground before it will show changes. I would expect changes to show up in my Mac UI without having to send app to background.
4
0
330
Jun ’24
SwiftData Remote Database Updates
I just saw the new SwiftData updates, including the DataStore API. I’m wondering if, in the case of a shared remote datastore, it is possible to enable updates to the model context from the datastore without the model context explicitly requesting them (e.g., through database listeners). If I’m not mistaken, when you use CloudKit with SwiftData, this happens, right?
1
0
180
Jun ’24
Access SwiftData in Widgets
How do I access the SwiftData ModelContainer of my app inside the widget extension? Following the guide to add a Widget Extension I’ve added the necessary target to my project and enabled App Groups. I’ve seen that the Backyard Birds example code offers an example how to build this, but it encapsulates the SwiftData handling in a separate app package. Therefore the example simply points to the app package. Though, in my case I don’t host my SwiftData in an external app package, but simply inside the regular app target. So, my question is how and at which point in code do I need to access the ModelContainer?
1
1
326
Jun ’24
Using Cloud Storage With SwiftData Custom Data Store
The following videos from WWDC24 say that we can use cloud storage for our SwiftData stores. Video references below: What's new in SwiftData Create a custom data store with SwiftData When watching the videos it shows examples of how we can read and write to a JSON file as a store, rather than using the built in store that comes with SwiftData. But there are mentions that we can use cloud storage like a backend i.e. a database hosted on a server. The only thing that I'm struggling to figure out and it would be great if we had code samples for this is how to achieve using cloud storage as a store since looking at the current implementations of: DataStoreConfiguration DataStore The required functions we need to implement look synchronous rather than asynchronous so how would or could we handle fetching asynchronous data from cloud storage. So how would we handle this? Also it would be great if someone could clarify how or if there is a way to send notifications for changes to your store between different devices similar to CloudKit? Are there there any plans to provide more documentation & sample code for the questions I've asked above? Feedback FB13857743
1
3
262
Jun ’24
SwiftData context disregards unique attribute
I have a simple model with a unique field. @Model class M { @Attribute(.unique) var value: String var date: Date var answer: Int init(value: String, date: Date = .now, answer: Int = 0) { self.value = value self.date = date self.answer = answer } } I am creating new objects with let x = M(value: "x") modelContext.insert(x) The value field has a unique constraint, and I am observing these differences in iOS 18 beta (Xcode 16.0 beta) from iOS 17.5 (Xcode 15.4): Multiple objects with the same value field appear in the list. If explicit modelContext.save() is called, list is not updated with latest values. Is this something I need to adjust to, or beta issues? Full source code: https://github.com/paiv/swiftdata-insert-unique-1
2
0
171
Jun ’24
Best way to share large CoreData model with extensions?
I have a large model. Not just large in complexity but literally there are gigabytes in the average user db. I want to enable saving data to this model from app extensions. However, I do not want to duplicate code or model setup. Is it recommended that I migrate to using a shared group model? How do you migrate existing stores to using shared containers? Or are there better ways to do it? For example, should I create a brand new store that uses a shared container? What are best practices?
1
0
188
Jun ’24
What does "Allows External Storage" checkbox in the Attribute Inspector do?
For a bit of context, I store binary files of about 50KB in my Core Data. I noticed that enabling the "Allows External Storage" option doesn't seem to make any difference. Additionally, how does this setting work with CloudKit when using NSPersistentCloudKitContainer? Does this setting affect how the data is loaded into memory when accessed in Core Data in the app? Thank you very much!
1
0
189
Jun ’24
Crash running app in iOS18
Hi, I updated my iPad to iOS18 beta 1, and it seems to crash my app immediately, even though it's the App Store release version that's running fine on iOS17. The crash report points to some issue in NSManagedObjectContext performBlockAndWait: Thread 2 name: Dispatch queue: NSManagedObjectContext 0x303498000: CJCloudKitItemsUploaderQueue Thread 2 Crashed: 0 libsystem_kernel.dylib 0x1f1930254 __pthread_kill + 8 1 libsystem_pthread.dylib 0x2285fcef8 pthread_kill + 268 2 libsystem_c.dylib 0x1a9a76ad8 abort + 128 3 CJournal 0x105428818 0x104e28000 + 6293528 4 CJournal 0x1054261f4 0x104e28000 + 6283764 5 CoreFoundation 0x1a1c40a3c __handleUncaughtException + 660 6 libobjc.A.dylib 0x19eec8210 _objc_terminate() + 132 7 CJournal 0x1053f5ad0 0x104e28000 + 6085328 8 libc++abi.dylib 0x22852087c std::__terminate(void (*)()) + 16 9 libc++abi.dylib 0x228520820 std::terminate() + 108 10 libdispatch.dylib 0x1a99bd174 _dispatch_client_callout + 40 11 libdispatch.dylib 0x1a99cc7b8 _dispatch_lane_barrier_sync_invoke_and_complete + 56 12 CoreData 0x1a9c94a6c -[NSManagedObjectContext performBlockAndWait:] + 264 13 ContactsJournalDataKit 0x10643fb50 -[CJCloudKitModifyRecordsOperation createUnderlyingCKModifyRecordsOperationWithProcessList:withLimit:] + 408 14 ContactsJournalDataKit 0x10643f544 -[CJCloudKitModifyRecordsOperation main] + 848 15 Foundation 0x1a071e2e0 __NSOPERATION_IS_INVOKING_MAIN__ + 16 16 Foundation 0x1a071c530 -[NSOperation start] + 648 17 Foundation 0x1a07947a0 __NSOPERATIONQUEUE_IS_STARTING_AN_OPERATION__ + 16 18 Foundation 0x1a07943ec __NSOQSchedule_f + 172 19 libdispatch.dylib 0x1a99cc350 _dispatch_block_async_invoke2 + 148 20 libdispatch.dylib 0x1a99bd160 _dispatch_client_callout + 20 21 libdispatch.dylib 0x1a99c0610 _dispatch_continuation_pop + 596 22 libdispatch.dylib 0x1a99bfc40 _dispatch_async_redirect_invoke + 580 23 libdispatch.dylib 0x1a99cedf4 _dispatch_root_queue_drain + 392 24 libdispatch.dylib 0x1a99cf5f8 _dispatch_worker_thread2 + 156 25 libsystem_pthread.dylib 0x2285f9c40 _pthread_wqthread + 228 26 libsystem_pthread.dylib 0x2285f6488 start_wqthread + 8 Can anyone shed some light on this? I haven't rebuilt the app with Xcode 16 yet, just wanted to run the App Store version and see if it's compatible without doing anything.
1
0
712
Jun ’24
iCloud reuploads whole desktop
I have my desktop in the iCloud. On a regular basis, my iCloud comes to a point where it wants to upload every single file again, so it sets every existing file on "Waiting for upload", and takes 3 – 5 days to reupload everything. I don’t know what causes this, it comes out of the blue sometimes. During that time, I can’t copy files, and can’t open some programs like Xcode. How can I avoid this?
2
0
257
May ’24
Local SwiftData to CloudKit migration
Hi, I've been working on an app that - so far - has only had to deal with offline data store. The usage is fairly simple: the user picks their favourite tv shows and networks, and they get persisted with SwiftData with all the correct relationships. Now, I would like to migrate the local storage of the users to a private CloudKit db, but every time I upgrade the app, the data seems to disappear completely. This is the snippet evolved through the attempt of migrating the data: Current Production code public static func makeModelContainer() -> ModelContainer { do { let processRequiresInMemory = ProcessInfo.processInfo.arguments.contains("inMemoryDatabasePreferred") let modelConfiguration = ModelConfiguration( isStoredInMemoryOnly: processRequiresInMemory, groupContainer: .automatic, cloudKitDatabase: .none ) let modelContainer = try ModelContainer( for: Country.self, Episode.self, Movie.self, Season.self, Show.self, Network.self, NetworkSubscription.self, migrationPlan: AppModelMigrationPlan.self, configurations: modelConfiguration ) return modelContainer } catch { fatalError("Could not initialize model container") } } Testing CloudKit enabled public static func makeModelContainer() -> ModelContainer { do { let processRequiresInMemory = ProcessInfo.processInfo.arguments.contains("inMemoryDatabasePreferred") let modelConfiguration = ModelConfiguration( "synced", isStoredInMemoryOnly: processRequiresInMemory, groupContainer: .automatic, cloudKitDatabase: .automatic ) let modelContainer = try ModelContainer( for: Country.self, Episode.self, Movie.self, Season.self, Show.self, Network.self, NetworkSubscription.self, migrationPlan: AppModelMigrationPlan.self, configurations: modelConfiguration ) return modelContainer } catch { fatalError("Could not initialize model container") } } } The differences, which I don't understand fully because I could not find documentation, are: ModelContainer(...) -> ModelContainer("synced", ...) cloudKitDatabase, from none to automatic. I have the feeling that changing the name of the configuration also changes some reference to the db itself, but if I were not to change the name, the app would have crashed because unable to migrate. What's the best approach to take here?
4
1
420
Jun ’24
Migrate Core Data to SwiftData in an App Group (& CloudKit)
Hello, I’m upgrading my app from Core Data to SwiftData. Due to my old setup the Core Data store has an explicitly name like „Something.sqlite“, because it was defined via NSPersistentContainer(name: "Something") before switching to SwiftData. Now my goal is to migrate the Core Data stack to SwiftData, while moving it to an App Group (for Widget support) as well as enable iCloud sync via CloudKit. Working Migration without App Group & CloudKit I’ve managed to get my migration running without migrating it to an App Group and CloudKit support like so: @main struct MyAppName: App { let container: ModelContainer init() { // Legacy placement of the Core Data file. let dataUrl = URL.applicationSupportDirectory.appending(path: "Something.sqlite") do { // Create SwiftData container with migration and custom URL pointing to legacy Core Data file container = try ModelContainer( for: Foo.self, Bar.self, migrationPlan: MigrationPlan.self, configurations: ModelConfiguration(url: dataUrl)) } catch { fatalError("Failed to initialize model container.") } } var body: some Scene { WindowGroup { ContentView() } .modelContainer(container) } } How To Migrate to App Group & CloudKit? I’ve already tried to use the ModelConfiguration with a name, but it seems to only look for a .store file and thus doesn’t copy over the Core Data contents. let fullSchema = Schema([Foo.self, Bar.self]) let configuration = ModelConfiguration("Something", schema: fullSchema) Can someone help me how to do this migration or point me into the right direction? I can’t find anything relating this kind of migration …
1
0
400
Jun ’24