iCloud & Data

RSS for tag

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

CloudKit Documentation

Posts under iCloud & Data subtopic

Post

Replies

Boosts

Views

Activity

Error - Never access a full future backing data
Hi, I am building an iOS app with SwiftUI and SwiftData for the first time and I am experiencing a lot of difficulty with this error: Thread 44: Fatal error: Never access a full future backing data - PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(backing: SwiftData.PersistentIdentifier.PersistentIdentifierBacking.managedObjectID(<ID> <x-coredata://<UUID>/MySwiftDataModel/p1>)), backing: SwiftData.PersistentIdentifier.PersistentIdentifierBacking.managedObjectID(<ID> <x-coredata://<UUID>/MySwiftDataModel/p1>)) with Optional(<UUID>) I have been trying to figure out what the problem is, but unfortunately I cannot find any information in the documentation or on other sources online. My only theory about this error is that it is somehow related to fetching an entity that has been created in-memory, but not yet saved to the modelContext in SwiftData. However, when I am trying to debug this, it's not clear this is the case. Sometimes the error happens, sometimes it doesn't. Saving manually does not always solve the error. Therefore, it would be extremely helpful if someone could explain what this error means and whether there are any best practices to do with SwiftData, or some pitfalls to avoid (such as wrapping my model context into a repository class). To be clear, this problem is NOT related to one area of my code, it happens throughout my app, at unpredictable places and time. Given that there is very little information related to this error, I am at a loss at how to make sure that this never happens. This question has been asked on the forum here as well as on StackOverflow, Reddit (can't link that here), but none of the answers worked for me. For reference, my models generally look like this: import Foundation import SwiftData @Model final class MySwiftDataModel { // Stable cross-device identity @Attribute(.unique) var uuid: UUID var someNumber: Int var someString: String @Relationship(deleteRule: .nullify, inverse: \AnotherSwiftDataModel.parentModel) var childModels: [AnotherSwiftDataModel] init(uuid: UUID = UUID(), someNumber: Int = 1, someString: String = "Some", childModels: [AnotherSwiftDataModel] = []) { self.uuid = uuid self.someNumber = someNumber self.someString = someString self.childModels = childModels } func addChildModel(model: AnotherSwiftDataModel) { self.childModels.append(model) } func removeChildModel(by id: PersistentIdentifier) { self.childModels = self.childModels.filter { $0.id != id } } } and the child model: import Foundation import SwiftData @Model final class AnotherSwiftDataModel { // Stable cross-device identity @Attribute(.unique) var uuid: UUID var someNumber: Int var someString: String var parentModel: MySwiftDataModel? init(uuid: UUID = UUID(), someNumber: Int = 1, someString: String = "Some") { self.uuid = uuid self.someNumber = someNumber self.someString = someString } } For now, you can assume I am not using CloudKit - i know for a fact the error is unrelated to CloudKit, because it happens when I am not using CloudKit (so I do not need to follow CloudKit's requirements for model design, such as nullable values etc). As I said, the error surfaces at different times - sometimes during assignments, a lot of times during deletions of related models, etc. Could you please explain what I am doing wrong and how I can make sure that this error does not happen? What are the architectural patterns that work best for SwiftData in this case? Do you have any examples of things I should avoid? Thanks
1
0
179
Jun ’25
Prevent data loss from delayed schema deployment
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.
0
0
149
Jun ’25
Odd, transient .badContainer error in CloudKit
I'm beta-testing a CloudKit-based app. One of my testers suddenly reported that they got a .badContainer CloudKit error: <CKError 0x302619800:"Bad Container" (5/1014); server message = "Invalid container to get bundle ids"; op = <...>; uuid = <...>; container ID = "<...>"> (all private info replaced with <...>) The container ID in the message was exactly what I expected, and exactly what other users are successfully using. When I followed up on the report, the user said she tried again later and everything was fine. It's still working fine days later. What could cause a user to get a .badContainer message, when all other users using the same app are fine, the container ID makes sense, and future runs work fine? Is this something I need to worry about? Does it maybe sometimes happen when CloudKit is having some kind of outage?
1
0
676
Jan ’25
Debugging/Fixing deleted relationship objects with SwiftData
Using SwiftData and this is the simplest example I could boil down: @Model final class Item { var timestamp: Date var tag: Tag? init(timestamp: Date) { self.timestamp = timestamp } } @Model final class Tag { var timestamp: Date init(timestamp: Date) { self.timestamp = timestamp } } Notice Tag has no reference to Item. So if I create a bunch of items and set their Tag. Later on I add the ability to delete a Tag. Since I haven't added inverse relationship Item now references a tag that no longer exists so so I get these types of errors: SwiftData/BackingData.swift:875: Fatal error: This model instance was invalidated because its backing data could no longer be found the store. PersistentIdentifier(id: SwiftData.PersistentIdentifier.ID(url: x-coredata://EEC1D410-F87E-4F1F-B82D-8F2153A0B23C/Tag/p1), implementation: SwiftData.PersistentIdentifierImplementation) I think I understand now that I just need to add the item reference to Tag and SwiftData will nullify all Item references to that tag when a Tag is deleted. But, the damage is already done. How can I iterate through all Items that referenced a deleted tag and set them to nil or to a placeholder Tag? Or how can I catch that error and fix it when it comes up? The crash doesn't occur when loading an Item, only when accessing item.tag?.timestamp, in fact, item.tag?.id is still ok and doesn't crash since it doesn't have to load the backing data. I've tried things like just looping through all items and setting tag to nil, but saving the model context fails because somewhere in there it still tries to validate the old value. Thanks!
2
0
361
Mar ’25
swiftdata model polymorphism?
I have a SwiftData model where I need to customize behavior based on the value of a property (connectorType). Here’s a simplified version of my model: @Model public final class ConnectorModel { public var connectorType: String ... func doSomethingDifferentForEveryConnectorType() { ... } } I’d like to implement doSomethingDifferentForEveryConnectorType in a way that allows the behavior to vary depending on connectorType, and I want to follow best practices for scalability and maintainability. I’ve come up with three potential solutions, each with pros and cons, and I’d love to hear your thoughts on which one makes the most sense or if there’s a better approach: **Option 1: Use switch Statements ** func doSomethingDifferentForEveryConnectorType() { switch connectorType { case "HTTP": // HTTP-specific logic case "WebSocket": // WebSocket-specific logic default: // Fallback logic } } Pros: Simple to implement and keeps the SwiftData model observable by SwiftUI without any additional wrapping. Cons: If more behaviors or methods are added, the code could become messy and harder to maintain. **Option 2: Use a Wrapper with Inheritance around swiftdata model ** @Observable class ParentConnector { var connectorModel: ConnectorModel init(connectorModel: ConnectorModel) { self.connectorModel = connectorModel } func doSomethingDifferentForEveryConnectorType() { fatalError("Not implemented") } } @Observable class HTTPConnector: ParentConnector { override func doSomethingDifferentForEveryConnectorType() { // HTTP-specific logic } } Pros: Logic for each connector type is cleanly organized in subclasses, making it easy to extend and maintain. Cons: Requires introducing additional observable classes, which could add unnecessary complexity. **Option 3: Use a @Transient class that customizes behavior ** protocol ConnectorProtocol { func doSomethingDifferentForEveryConnectorType(connectorModel: ConnectorModel) } class HTTPConnectorImplementation: ConnectorProtocol { func doSomethingDifferentForEveryConnectorType(connectorModel: ConnectorModel) { // HTTP-specific logic } } Then add this to the model: @Model public final class ConnectorModel { public var connectorType: String @Transient public var connectorImplementation: ConnectorProtocol? // Or alternatively from swiftui I could call myModel.connectorImplementation.doSomethingDifferentForEveryConnectorType() to avoid this wrapper func doSomethingDifferentForEveryConnectorType() { connectorImplementation?.doSomethingDifferentForEveryConnectorType(connectorModel: self) } } Pros: Decouples model logic from connector-specific behavior. Avoids creating additional observable classes and allows for easy extension. Cons: Requires explicitly passing the model to the protocol implementation, and setup for determining the correct implementation needs to be handled elsewhere. My Questions Which approach aligns best with SwiftData and SwiftUI best practices, especially for scalable and maintainable apps? Are there better alternatives that I haven’t considered? If Option 3 (protocol with dependency injection) is preferred, what’s the best way to a)manage the transient property 2) set the correct implementation and 3) pass reference to swiftdata model? Thanks in advance for your advice!
0
0
478
Jan ’25
ModelContext.model(for:) returns deleted objects
I'm writing some tests to confirm the behavior of my app. White creating a model actor to delete objects I realized that ModelContext.model(for:) does return objects that are deleted. I was able to reproduces this with this minimal test case: @Model class Activity { init() {} } struct MyLibraryTests { let modelContainer = try! ModelContainer( for: Activity.self, configurations: ModelConfiguration( isStoredInMemoryOnly: true ) ) init() throws { let context = ModelContext(modelContainer) context.insert(Activity()) try context.save() } @Test func modelForIdAfterDelete() async throws { let context = ModelContext(modelContainer) let id = try context.fetch(FetchDescriptor<Activity>()).first!.id context.delete(context.model(for: id) as! Activity) try context.save() let result = context.model(for: id) as? Activity #expect(result == nil) // Expectation failed: (result → MyLibrary.Activity) == nil } @Test func fetchDescriptorAfterDelete() async throws { let context = ModelContext(modelContainer) let id = try context.fetch(FetchDescriptor<Activity>()).first!.id context.delete(context.model(for: id) as! Activity) try context.save() let result = try context.fetch( FetchDescriptor<Activity>(predicate: #Predicate { $0.id == id }) ).first #expect(result == nil) } } Here I create a new context, insert an model and save it. The test modelForIdAfterDelete does fail, as result still contains the deleted object. I also tried to check #expect(result!.isDeleted), but it is also false. With the second test I use a FetchDescriptor to retrieve the object by ID and it correctly returns nil. Shouldn't both methods use a consistent behavior?
2
0
126
May ’25
Mutating an array of model objects that is a child of a model object
Hi all, In my SwiftUI / SwiftData / Cloudkit app which is a series of lists, I have a model object called Project which contains an array of model objects called subprojects: final class Project1 { var name: String = "" @Relationship(deleteRule: .cascade, inverse: \Subproject.project) var subprojects : [Subproject]? init(name: String) { self.name = name self.subprojects = [] } } The user will select a project from a list, which will generate a list of subprojects in another list, and if they select a subproject, it will generate a list categories and if the user selects a category it will generate another list of child objects owned by category and on and on. This is the pattern in my app, I'm constantly passing arrays of model objects that are the children of other model objects throughout the program, and I need the user to be able to add and remove things from them. My initial approach was to pass these arrays as bindings so that I'd be able to mutate them. This worked for the most part but there were two problems: it was a lot of custom binding code and when I had to unwrap these bindings using init?(_ base: Binding<Value?>), my program would crash if one of these arrays became nil (it's some weird quirk of that init that I don't understand at al). As I'm still learning the framework, I had not realized that the @model macro had automatically made my model objects observable, so I decided to remove the bindings and simply pass the arrays by reference, and while it seems these references will carry the most up to date version of the array, you cannot mutate them unless you have access to the parent and mutate it like such: project.subcategories?.removeAll { $0 == subcategory } project.subcategories?.append(subcategory) This is weirding me out because you can't unwrap subcategories before you try to mutate the array, it has to be done like above. In my code, I like to unwrap all optionals at the moment that I need the values stored in them and if not, I like to post an error to the user. Isn't that the point of optionals? So I don't understand why it's like this and ultimately am wondering if I'm using the correct design pattern for what I'm trying to accomplish or if I'm missing something? Any input would be much appreciated! Also, I do have a small MRE project if the explanation above wasn't clear enough, but I was unable to paste in here (too long), attach the zip or paste a link to Google Drive. Open to sharing it if anyone can tell me the best way to do so. Thanks!
5
0
222
Sep ’25
SwiftData Fatal error
I'm developing an app that uses CloudKit synchronization with SwiftData and on visionOS I added an App Settings bundle. I have noticed that sometimes, when the app is open and the user changes a setting from the App Settings bundle, the following fatal error occurs: SwiftData/BackingData.swift:831: Fatal error: This model instance was destroyed by calling ModelContext.reset and is no longer usable. The setting is read within the App struct in the visionOS app target using @AppStorage and this value is in turn used to set the passthrough video dimming via the .preferredSurroundingsEffect modifier. The setting allows the user to specify the dimming level as dark, semi dark, or ultra dark. The fatal error appears to occur intermittently although the first time it was observed was after adding the settings bundle. As such, I suspect there is some connection between those code changes and this fatal error even though they do not directly relate to SwiftData.
1
0
258
Oct ’25
CloudKit console fails to query indexed records in Production
"No records found" If I create a new record on the console, I can copy the record name. I can then query for recordName and get that individual record back. BUT no other queries work. I cannot query all records. I cannot query by individual property. Just returns "no records found" Seems like my indexes got messed up. Is there a way to reset indexes on prod? This is on a coredata.cloudkit managed zone.
1
0
106
Aug ’25
CKShare Fails with quotaExceeded Error on Family iCloud Plan
Hello, When attempting to create a CKShare on a personal device linked to a Family iCloud plan (non-primary account holder), the operation fails with a quotaExceeded error. This occurs with the Family plan having 1.5TB available storage space. This is also causing a data loss for the object(s) that were attempted to be shared. Details Account Type: Family iCloud Plan (2TB total storage) Current Family Usage: 399GB iCloud Account Usage: 70 GB Steps to Reproduce: Have an iCloud account with storage over the 5GB free space limit. Be on a part of a iCloud Family Plan as the non-primary account holder. Have storage space available in the Family Plan Attempt to start a CloudKit Share/Collaboration on the device. Observe that the CKShare creation fails with a quotaExceeded error. Expected Behavior: The CKShare should be successfully created, reflecting the total available storage of the Family plan. Observed Behavior: The CKShare fails to be created with quotaExceeded. Additional Testing On a test device using an iCloud account with no stored data, the CKShare was created successfully and shared without issue. Suspected Cause The CKShare functionality is verifying the personal storage allocation of the iCloud account and failing without checking total available storage provided by the Family plan.
2
0
762
Jan ’25
Swift 6 Concurrency errors with ModelActor, or Core Data actors
In my app, I've been using ModelActors in SwiftData, and using actors with a custom executor in Core Data to create concurrency safe services. I have multiple actor services that relate to different data model components or features, each that have their own internally managed state (DocumentService, ImportService, etc). The problem I've ran into, is that I need to be able to use multiple of these services within another service, and those services need to share the same context. Swift 6 doesn't allow passing contexts across actors. The specific problem I have is that I need a master service that makes multiple unrelated changes without saving them to the main context until approved by the user. I've tried to find a solution in SwiftData and Core Data, but both have the same problem which is contexts are not sendable. Read the comments in the code to see the issue: /// This actor does multiple things without saving, until committed in SwiftData. @ModelActor actor DatabaseHelper { func commitChange() throws { try modelContext.save() } func makeChanges() async throws { // Do unrelated expensive tasks on the child context... // Next, use our item service let service = ItemService(modelContainer: SwiftDataStack.shared.container) let id = try await service.expensiveBackgroundTask(saveChanges: false) // Now that we've used the service, we need to access something the service created. // However, because the service created its own context and it was never saved, we can't access it. let itemFromService = context.fetch(id) // fails // We need to be able to access changes made from the service within this service, /// so instead I tried to create the service by passing the current service context, however that results in: // ERROR: Sending 'self.modelContext' risks causing data races let serviceFromContext = ItemService(context: modelContext) // Swift Data doesn't let you create child contexts, so the same context must be used in order to change data without saving. } } @ModelActor actor ItemService { init(context: ModelContext) { modelContainer = SwiftDataStack.shared.container modelExecutor = DefaultSerialModelExecutor(modelContext: context) } func expensiveBackgroundTask(saveChanges: Bool = true) async throws -> PersistentIdentifier? { // Do something expensive... return nil } } Core Data has the same problem: /// This actor does multiple things without saving, until committed in Core Data. actor CoreDataHelper { let parentContext: NSManagedObjectContext let context: NSManagedObjectContext /// In Core Data, I can create a child context from a background context. /// This lets you modify the context and save it without updating the main context. init(progress: Progress = Progress()) { parentContext = CoreDataStack.shared.newBackgroundContext() let childContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType) childContext.parent = parentContext self.context = childContext } /// To commit changes, save the parent context pushing them to the main context. func commitChange() async throws { // ERROR: Sending 'self.parentContext' risks causing data races try await parentContext.perform { try self.parentContext.save() } } func makeChanges() async throws { // Do unrelated expensive tasks on the child context... // As with the Swift Data example, I am unable to create a service that uses the current actors context from here. // ERROR: Sending 'self.context' risks causing data races let service = ItemService(context: self.context) } } Am I going about this wrong, or is there a solution to fix these errors? Some services are very large and have their own internal state. So it would be very difficult to merge all of them into a single service. I also am using Core Data, and SwiftData extensively so I need a solution for both. I seem to have trapped myself into a corner trying to make everything concurrency save, so any help would be appreciated!
6
0
877
Mar ’25
Request to manually associate my CloudKit container with my app ID
Hello, My app has had CloudKit enabled for a while, but it's not working. I get the error "Invalid bundle ID for container". Configure CloudKit in your project from TN3164 suggests changing to a new container. I tried changing to a new container, but this leads to data loss. The article recommends: "If your CloudKit container is already used in the production environment and switching to a new container leads to data loss, consider filing a feedback report with the following information to request manually associating your CloudKit container with your app ID." Where can I request this manual association? Is there anything else I can do? Thank you for your time and assistance. I’d appreciate a prompt resolution, as this issue is blocking our update. Looking forward to guidance.
2
0
524
Mar ’25
How to get PersistentIdentifier from a model created in a transaction?
I have a ModelActor that creates a hierarchy of models and returns a PersistentIdentifier for the root. I'd like to do that in a transaction, but I don't know of a good method of getting that identifier if the models are created in a transaction. For instance, an overly simple example: func createItem(timestamp: Date) throws -> PersistentIdentifier { try modelContext.transaction { let item = Item(timestamp: timestamp) modelContext.insert(item) } // how to return item.persistentModelID? } I can't return the item.persistentModelID from the transaction closure and even if I could, it will be a temporary ID until after the transaction is executed. I can't create the Item outside the transaction and just have the transaction do an insert because swift will raise a data race error if you then try to return item.persistentModelID. Is there any way to do this besides a modelContext.fetch* with separate unique identifiers?
2
0
219
Aug ’25
Can't access child entries of SwiftData class
When I tried to use a working project with iOS 18 installed on my device, it wouldn't work anymore and crash right away. Before with iOS 17 it was working fine. I can't access child variables that are saved in an Array in a parent object in SwiftData. The error is always somewhere in these hidden lines: { @storageRestrictions(accesses: _$backingData, initializes: _title) init(initialValue) { _$backingData.setValue(forKey: \.title, to: initialValue) _title = _SwiftDataNoType() } get { _$observationRegistrar.access(self, keyPath: \.title) return self.getValue(forKey: \.title) } set { _$observationRegistrar.withMutation(of: self, keyPath: \.title) { self.setValue(forKey: \.title, to: newValue) } } } The child classes are also inserted and saved into the modelContext when created and set to the parent instance, but I also can't fetch them via modelContext.fetch() - Error here is: Thread 1: EXC_BREAKPOINT (code=1, subcode=0x243a62a4c) Maybe there is a problem with the relationship between two saved instances. The parent instances are saved correctly and it was working in iOS 17. The problem is similar to these two cases: https://forums.developer.apple.com/forums/thread/762679 https://forums.developer.apple.com/forums/thread/738983 I changed the logic after I reviewed these threads, as I am now linking the parent and child instances, that got rid of one warning in the console. button.canvas = canvas modelContext.insert(button) canvas.buttons = [button] But in the end those threads were not enough for me to find a fix for my problem. A small project can be found here: https://github.com/DonMalte/SwiftDataTest
3
0
835
Jan ’25
dual predicate search using CoreData
I have a very simple CoreData model that has 1 entity and 2 attributes. This code works fine: .onChange(of: searchText) { _, text in evnts.nsPredicate = text.isEmpty ? nil :NSPredicate(format: "eventName CONTAINS %@ " , text ) but I'd like to also search with the same text string for my second attribute (which is a Date). I believe an OR is appropriate for two conditions (find either one). See attempted code below: evnts.nsPredicate = text.isEmpty ? nil : NSPredicate(format: "(eventName CONTAINS %@) OR (dueDate CONTAINS %i) " , text ) This crashes immediately %@ does the same. Is there a way to accomplish this? How is SwiftUI not an option below?
6
0
359
Mar ’25
SwiftData serious bug with relationships and CloudKit in iOS 18.0 (Xcode 16 Beta)
Hi guys. Can someone please confirm this bug so I report it? The issue is that SwiftData relationships don't update the views in some specific situations on devices running iOS 18 Beta. One clear example is with CloudKit. I created a small example for testing. The following code creates two @models, one to store bands and another to store their records. The following code works with no issues. (You need to connect to a CloudKit container and test it on two devices) import SwiftUI import SwiftData struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var records: [Record] var body: some View { NavigationStack { List(records) { record in VStack(alignment: .leading) { Text(record.title) Text(record.band?.name ?? "Undefined") } } .toolbar { ToolbarItem { Button("Add Record") { let randomNumber = Int.random(in: 1...100) let newBand = Band(name: "New Band \(randomNumber)", records: nil) modelContext.insert(newBand) let newRecord = Record(title: "New Record \(randomNumber)", band: newBand) modelContext.insert(newRecord) } } } } } } @Model final class Record { var title: String = "" var band: Band? init(title: String, band: Band?) { self.title = title self.band = band } } @Model final class Band { var name: String = "" var records: [Record]? init(name: String, records: [Record]?) { self.name = name self.records = records } } This view includes a button at the top to add a new record associated with a new band. The data appears on both devices, but if you include more views inside the List, the views on the second device are not updated to show the values of the relationships. For example, if you extract the row to a separate view, the second device shows the relationships as "Undefined". You can try the following code. struct ContentView: View { @Environment(\.modelContext) private var modelContext @Query private var records: [Record] var body: some View { NavigationStack { List { ForEach(records) { record in RecordRow(record: record) } } .toolbar { ToolbarItem { Button("Add Record") { let randomNumber = Int.random(in: 1...100) let newBand = Band(name: "New Band \(randomNumber)", records: nil) modelContext.insert(newBand) let newRecord = Record(title: "New Record \(randomNumber)", band: newBand) modelContext.insert(newRecord) } } } } } } struct RecordRow: View { let record: Record var body: some View { VStack(alignment: .leading) { Text(record.title) Text(record.band?.name ?? "Undefined") } } } Here I use a ForEach loop and move the row to a separate view. Now on the second device the relationships are nil, so the row shows the text "Undefined" instead of the name of the band. I attached an image from my iPad. I inserted all the information on my iPhone. The first three rows were inserted with the first view. But the last two rows were inserted after I extracted the rows to a separate view. Here you can see that the relationships are nil and therefore shown as "Undefined". The views are not updated to show the real value of the relationship. This example shows the issue with CloudKit, but this also happens locally in some situations. The system doesn't detect updates in relationships and therefore doesn't refresh the views. Please, let me know if you can reproduce the issue. I'm using Mac Sequoia 15.1, and two devices with iOS 18.0.
3
0
833
Apr ’25
iOS 17.2 Update, Confusing SwiftData Update !
Hi, Before the iOS 17.2 update the saving behavior of SwiftData was very straightforward, by default it saves to persistence storage and can be configured to save in memory only. Now it saves to memory by default and to make it save to persistence storage we need to use modelContext.Save(). But if we don't quit the App the changes will be saved after a while to persistence storage even without running modelContext.Save() ! How confusing can that be for both developer and the user ! Am I missing something here ? -- Kind Regards
3
0
438
Mar ’25
How to force / wait for SwiftData sync on first app launch?
I have a SwiftData application that is using CloudKit. If user is on new device. How can I check and fetch data, instead of just waiting for it happen on its own randomly? For example, I have onboarding which I do not want user to go through again if they already have an active installation. Seems like SwiftData is severely limited in pretty much every way, specially any useful CloudKit debugging or control functionality.
2
0
343
Mar ’25