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

Why is PersistentModel a protocol and not a class?
PersistentModel is a protocol but would make more sense as a class that we then subclass. If all of the implementation was in a parent class of our model classes then there wouldn't be all the problems caused by requiring the use of the @Model macro, e.g. default property values not working, unable to subclass, overriding get/set not possible, conflict in property names...
0
0
564
Aug ’23
File size limit?
I keep getting crashes with the following error in Xcode 15 beta 7: CoreData: debug: PostSaveMaintenance: fileSize 15009192 greater than prune threshold CoreData: annotation: PostSaveMaintenance: wal_checkpoint(TRUNCATE) Is 15M bytes too much data?
2
0
803
Aug ’23
How to upload default-data to the public CloudKit database
I need some help understanding how the public database works in CloudKit. First of all, let me say that I know how to connect and use the private database. In this question I'm not looking for an answer on how to connect to the database at self, only the concept. Here is my confusion. I have a set of images that all users in my app will be using, right now what I'm doing is adding the images directly to the app (an Image Set in Xcode) and then I am pulling them to Core Data and then syncing them to CloudKit. As you can see all images are technically stored in every device using my app and in Core Data/CloudKit, not very efficient. What I would like is to have the images stored in a single place where all uses can pull the images from, in this case CloudKit. I know I can have them somewhere in a private server, but I feel like I would be adding more complexity to my app, so I think using CloudKit is a better option for me. Here is my question. How do I get the images to CloudKit, do I upload them directly to CloudKit and then read from all devices or do I need to first add them to a device and upload to CloudKit from there? Thanks!
2
0
596
Aug ’23
In SwiftData when encoding/decoding Predicate, what's the reason for PredicateCodableConfiguration?
I'm converting a project that previously stored some NSPredicates as the string format. When converting to SwiftData I discovered Predicate is Codable, which makes things nice... except for PredicateCodableConfiguration. From what I understand you have to specify every model and key you use in the predicate or the encode/decode fails. This is kind of a pain, because you already define this in the Predicate. Does anyone know what the reason for this is? There's also PredicateCodableKeyPathProviding which lets you define the keys for a class all at once, which makes it slightly easier. But if SwiftData is intended to reduce boilerplate code, why does the Predicate itself not provide enough detail about what to encode/decode?
0
0
289
Sep ’23
Missing Desktop and Documents and Error 8072
Yesterday 8/31/23 around 2:00 pm I deleted documents from my iPhone - apparently I wasn't paying attention and it was deleted from iCloud Drive. I later was on my MacBook Pro running Ventura 13.5 and my desktop and folders are gone... I logged into iCloud and there is nothing under recently deleted. When I try to right click anywhere on the desktop I get The operation can't be completed a unexpected error occurred - error 8072. When I go into finder I try to click desktop or documents I get- The operation can’t be completed because the original item for “Documents” can’t be found. The operation can’t be completed because the original item for “Desktop” can’t be found. I have gone into finder setting check - unchecked everything that I could from reading threads. I have started in safe mode I have run disk utility I logged out go Apple ID and back in... When I try to check the desktop and documents folder in settings it turns on and off quickly. I can turn it on through Settings general - storage. I am very frustrated and upset I did not ever choose permanently delete. Any help would be GREATLY appreciated. Thanks - Kim
1
0
706
Sep ’23
Unable to deduplicate both private and public store
I've successfully followed the sample code from Apple: Synchronizing a local store to the cloud to deduplicate entities that are created in the user's private store. However my app also has a public store that needs deduplication and if I enable the NSPersistentStoreRemoteChangeNotificationPostOptionKey for both the private and public store then no deduplication will occur in my private store. This is reproducible every time by not setting NSPersistentStoreRemoteChangeNotificationPostOptionKey for the public store. Has anyone else experienced this and has anyone got a solution to get it to work? Persistence setup code: private static func makeStoreDescription(for database: Database) -> NSPersistentStoreDescription { let url: URL let scope: CKDatabase.Scope let configuration: String switch database { case .private: url = Self.privateStoreURL scope = .private configuration = "Private" case .public: url = Self.publicStoreURL scope = .public configuration = "Public" } let storeDescription = NSPersistentStoreDescription(url: url) storeDescription.cloudKitContainerOptions = .init(containerIdentifier: Config.cloudKitContainerIdentifier) storeDescription.cloudKitContainerOptions?.databaseScope = scope switch database { case .private: storeDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) storeDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) case .public: // Uncommented otherwise deduplication doesn't work // storeDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) // storeDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) break } storeDescription.configuration = configuration return storeDescription } private static func makeContainer(inMemory: Bool = false, useIcloud: Bool) -> NSPersistentCloudKitContainer { let privateStoreDescription = makeStoreDescription(for: .private) let publicStoreDescription = makeStoreDescription(for: .public) let container = NSPersistentCloudKitContainer(name: "Name", managedObjectModel: managedObjectModel) container.persistentStoreDescriptions = [privateStoreDescription, publicStoreDescription] // Don't save information for future use if running in memory... if inMemory { container.persistentStoreDescriptions.forEach { $0.url = URL(fileURLWithPath: "/dev/null") } } print("useIcloud:", useIcloud) if !useIcloud { container.persistentStoreDescriptions.forEach { $0.cloudKitContainerOptions = nil } } container.loadPersistentStores { storeDescription, error in if let error = error as NSError? { fatalError("Unresolved error \(error), \(error.userInfo)") } print("Loaded store configuration:", storeDescription.configuration ?? "") } #if DEBUG // Use the container to initialize the development schema. // Only necessary whenever changes have been made to the schema. //try! container.initializeCloudKitSchema(options: []) #endif container.viewContext.automaticallyMergesChangesFromParent = true container.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump container.viewContext.transactionAuthor = Self.transactionAuthor if !inMemory { do { try container.viewContext.setQueryGenerationFrom(.current) } catch { fatalError("Failed to pin viewContext to the current generation: \(error)") } } return container }
0
0
352
Sep ’23
SwiftData Model class not triggering observation of computed property that depends on relationship
I created FB13074428 and a small sample project to demonstrate the bug. https://github.com/jamiemcd/Apple-FB13074428 Basically, if a SwiftData class is marked as @Model and it has a computed property that depends on a relationship's stored property, the computed property does not trigger updates in SwiftUI when the underlying relationship changes its stored property. This is Xcode 15 Beta 8. @Model final class Airport { var code: String var name: String var airplanes: [Airplane] init(code: String, name: String, airPlanes: [Airplane]) { self.code = code self.name = name self.airplanes = airPlanes } // Bug: This computed property is not triggering observation in AirportView when airplane.state changes. My understanding of the new observation framework is that it should. var numberOfAirplanesDeparting: Int { var numberOfAirplanesDeparting = 0 for airplane in airplanes { if airplane.state == .departing { numberOfAirplanesDeparting += 1 } } return numberOfAirplanesDeparting } } AirportView should update because it has Text for airport.numberOfAirplanesDeparting struct AirportView: View { var airport: Airport var body: some View { List { Section { ForEach(airport.airplanes) { airplane in NavigationLink(value: airplane) { HStack { Image(systemName: airplane.state.imageSystemName) VStack(alignment: .leading) { Text(airplane.name) Text(airplane.type.name) } } } } } header: { Text(airport.name) } footer: { VStack(alignment: .leading) { Text("Planes departing = \(airport.numberOfAirplanesDeparting)") Text("Planes in flight = \(airport.numberOfAirplanesInFlight)") Text("Planes landing = \(airport.numberOfAirplanesLanding)") } } } }
4
3
1.4k
Sep ’23
How do I filter @Query with bound item
I have a few that is passed an item of type FamilyMember. Available in the view is a list of Chores. A chore has a member assigned to it. I want to filter the chores to the passed family member. 2 Structures and view code: @Model class Chore: Identifiable { @Attribute(.unique) var id = UUID() var name: String var frequency: ChoreFrequency var assignedTo: FamilyMember var isComplete: Bool var dueDate: Date init(id: UUID = UUID(), name: String = "", frequency: ChoreFrequency = .daily, assignedTo: FamilyMember = FamilyMember(), isComplete: Bool = false, dueDate: Date = Date()) { self.name = name self.frequency = frequency self.assignedTo = assignedTo self.isComplete = isComplete self.dueDate = dueDate } } @Model class FamilyMember: Identifiable { @Attribute(.unique) var id: String { name } var name: String init(name: String = "Unassigned") { self.name = name } } struct MemberView: View { @Bindable var member: FamilyMember @Query private var chores: [Chore] init(member: FamilyMember) { self.member = member let predicate = #Predicate<Chore> { $0.assignedTo == member // <— Error occurs here! } _chores = Query(filter: predicate, sort: \.dueDate) } . . . It's when creating the predicate that I'm running to an error of value conversion. Cannot convert value of type 'PredicateExpressions.Equal<PredicateExpressions.KeyPath<PredicateExpressions.Variable<Chore>, FamilyMember>, PredicateExpressions.Value<FamilyMember>>' to closure result type 'any StandardPredicateExpression<Bool>' What am I doing wrong?
2
0
850
Sep ’23
Is SwiftUI Picker not compatible with a Bindable property?
I have a view with @Bindable property. (It's a model) I can use TextField("Name", text: $chore.name), but not Picker(selection: $chore.choreFrequency, label: EmptyView()) The auto-complete doesn't even show choreFrequency as an option enum ChoreFrequency: String, CaseIterable, Identifiable, Codable { case daily, weekly, monthly, seasonal var id: ChoreFrequency { self } } @Model class Chore: Identifiable { @Attribute(.unique) var id = UUID() var name: String var frequency: ChoreFrequency var assignedTo: FamilyMember var isComplete: Bool var dueDate: Date } Can I not use the Bindable property in the Picker?
3
0
714
Sep ’23
CoreData permanentID set only for root context of persistentCoordinator
Hello. I had some problems related to objectID, let me try to describe it. I had 3 managed object contexts: context A - root private context of persistentCoordiantor, used for write changes to persistentStore. retainsRegisteredObjects = false context B - main context, parent context - A. retainsRegisteredObjects = true context C - background private context. parent context - B. retainsRegisteredObjects = true When I add new MO to coreData, it saved succesfully to all contexts , but, when I check registeredObjects of context B and C, objectID for new MO is temporary, this is problem for me, because I had some work with coreData from NotificationServiceExtension, and I use fetch persistent history to get updates that was made in NSE and apply them to main app, but, in fetch history I get changes for MO that have permanentID, but in my context B and C there is still temporaryID. It was strange for me, so, I set retainsRegisteredObjects to context A, after that, I noticed, that after save new MO to coreData, permanentID is set only in context A for that MO, in contexts B and C MO still have temporaryID, does it correct behaviour of coreData or it's bug? I expect that when I save MO to coreData, it will automatically update ID as permanent for MO in all context for this MO if it exist in registeredObjects of certain context
0
0
331
Sep ’23
SwiftData Many to One Cascade Delete not working as I expect in Xcode15 Beta 7 & 8
This approach worked in Beta 5, but does not work in Betas 7 & 8. (I skipped Beta 6, so I don't know if it worked then). I'm not sure if it's a SwiftData bug or a mistake on my part since the API has changed since the WWDC video. (I opened Apple Feedback: FB13120831) I am trying to implement a cascade delete on a many to one relationship. See the two models below. When I deleted the Recipe Model object, I expect that any of the FoodMenus that have that recipe will also be deleted. But they are not. The Recipe is deleted and the FoodMenu is still there. When I put a deleteRule: .cascade on the FoodMenu.recipe, the cascade does work. The Menu and the Associated recipe are both deleted. But that's not the behavior I want. @Model final class Recipe { var name: String var id: UUID @Relationship(deleteRule: .cascade, inverse: \FoodMenu.recipe) var menus: [FoodMenu]? init(name: String, id: UUID, menus: [FoodMenu]? = []) { self.name = name self.id = id self.menus = menus } } @Model final class FoodMenu { var name: String var id: UUID var recipe: Recipe? = nil //I believe the below definition should be the same behavior as above and it works as expected. relationship is nullified when the FoodMenu is deleted. Recipe left in place. // @Relationship (deleteRule: .nullify, inverse: \Recipe.menus) // var recipe: Recipe? = nil init(name: String, id: UUID) { self.name = name self.id = id } }
1
0
1k
Sep ’23
'ID' is inaccessible due to '@_spi' protection level
When I reference the ID of a SwiftData model entity (aka PersistentIdentifier) anywhere as a type (like @State var selection: Set<SomeEntity.ID> = Set<SomeEntity.ID>()) I now get the following error: 'ID' is inaccessible due to '@_spi' protection level This never was a problem with CoreData and also not with SwiftData until the Xcode 15 RC. Does anybody know, if this is a bug or intended behaviour?
3
2
1.2k
Sep ’23
CKQueryOperation returns new cursor, but no results, eventually rejects requests
In my app, I am using CloudKit and one thing I need to do is to query all records of a certain record type. I am creating a CKQueryOperation with the record type I am interested in, leaving the rest to the defaults basically (resultsLimit, desiredKeys, qualityOfService etc). Most times, the app does not return any results at all, but does return a queryCursor, indicating there are more results to fetch. So I add a new CKQueryOperation with a CKQuery created with the returned queryCursor. But the same thing happens again (most of the times) - no results (or maybe a single result) and a new queryCursor. This goes on and on until either all results are returned (which usually is not the case) or CloudKit errors out with "Server rejected the request" (perhaps for rate-limiting reasons?). The same behaviour can be observed when using the CloudKit web API, and it doesn't seem to matter what values I set for resultsLimit, desiredKeys, qualityOfService etc... So, what am I doing wrong? How can I query all records of a record type without errors?
2
0
365
Sep ’23