CloudKit

RSS for tag

Store structured app and user data in iCloud containers that can be shared by all users of your app using CloudKit.

Posts under CloudKit tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

NSPersistentCloudKitContainer CKRecord conversion errors
I'm using NSPersistentCloudKitContainer with my app and everything has been working fine for the most part. However, every now and then I come across an entity that saves fine into core data but then can't sync to cloud kit and causes the entire cloud kit feature to stop working. The error happens when starting the app and looks like this: error: CoreData+CloudKit: -NSCloudKitMirroringDelegate _requestAbortedNotInitialized:: <NSCloudKitMirroringDelegate: 0x2820187e0> - Never successfully initialized and cannot execute request '<NSCloudKitMirroringImportRequest: 0x283a27930> 3CD51F2A-E632-4FF0-8B8C-C17DCB15A002' due to error: <CKError 0x281739a10: "Partial Failure" (2/1011); "Failed to modify some records"; uuid = 9C4B94E0-662F-4B75-894B-55AD51DE9C79; container ID = "iCloud.com.mrsdizzie.LaurasBooks"; partial errors: { 0A2C0554-254E-47AA-B2C5-58F6C1CA038E:(com.apple.coredata.cloudkit.share.164680EE-7664-4105-9039-2FA952A013AB:__defaultOwner__) = <CKError 0x28173a6a0: "Invalid Arguments" (12/2006); server message = "Cannot create or modify field 'CD_data_ckAsset' in record 'CD_ImageData' in production schema"; op = 065A25FC65E7BB30; uuid = 9C4B94E0-662F-4B75-894B-55AD51DE9C79> ... 3 "Batch Request Failed" CKError's omited ... }> The app is for keeping track of Books, so the basic data model is an entity named Book with a relationship named imageData. This maps to an entity named ImageData with a field named data. data is of type "binary data" and where the cover image for a particular book is stored. This has worked so far for hundreds of entries into core data and cloud kit, but every now and then I see an error like this in the console app and the only way to recover is delete the offending entry (either manually, or by removing the app which deletes all local data). I am now able to reproduce it with one particular entry on one device in production, but not sure how to proceed from there. Since all of this syncing and creation of CKRecords happens automatically via NSPersistentCloudKitContainer I'm not really sure what to do, how to recover, or how to get more details about what it doesn't like in this particular case. I've monitored NSPersistentCloudKitContainer.eventNotificationUserInfoKey for event errors but only get short errors like: CKError Domain: 2, Description: The operation couldn't be completed The production schema is up to date and hasn't changed. Most entries into the app work fine. It is only every so often with certain entries that this error happens. There is no obvious difference between entries that I can see. The image itself in this and other cases is under 1MB. Any advice appreciated. Thanks!
4
1
699
Jul ’23
Refresh view with new CloudKit records
Hello, I'm new to iOS development and I need help for working with CloudKit. I have an application that allows me to add, delete and display information stored in a CloudKit container. When I try to add a new record, this one can be visible into my CloudKit Console but if don't switch to a other view and back to my view (with my list of records) the record isn't displayed. How can I update my list to reflect directly the new record add to my container ? This is my code with split into different files (in attachment) Sets : define my record struct SetsView: list of my records AddSetView: add new records AddSetView-ViewModel : view model with my add function SetsView-ViewModel: view model with my fetch function Add function : func add() async throws { var newSet = set newSet.name = name newSet.code = code newSet.releaseDate = releaseDate newSet.numberOfCards = numberOfCards let record = try await db.save(newSet.set) guard let set = Set(record: record) else { return } setsDictionary[set.id!] = set print("Set added") } Fetch function : func fetchSets() async throws { let query = CKQuery(recordType: SetRecordKeys.type.rawValue, predicate: NSPredicate(value: true)) query.sortDescriptors = [NSSortDescriptor(key: "name", ascending: false)] let result = try await db.records(matching: query) // récupère les données qui correspondent aux critères let records = result.matchResults.compactMap { try? $0.1.get() } // Récupère les records sets.removeAll() records.forEach { record in sets.append(Set(record: record)!) } print("Sets fetched") print(sets) } Set.txt SetsView.txt AddSetView.txt AddSetView-ViewModel.txt SetsView-ViewModel.txt I try to add some print to figure out what's going on, but I don't understand. This is the console log for this scenario : open app without any data into the container > add a new record First, the fetch function is executed but there is no data into the container (it's logic) Second I add a new record (Set) : Into the CloudKit console the new Set is visible So for refresh my view with this record I need to re-call the fetch function. I tried many things but nothing works. Even if the fetch function is called, the new record is not retrieved. Do you have any idea how to solve this problem? Thanks for your help.
0
0
561
Jul ’23
User Name components
Trying to build an app that shares data across users, and one sanity check I was using was to check that the current user has granted permission to be looked up, and then I could display the user's name in the view. Previously, I could check the applicationPermissionStatus with CKContainer.applicationPermissionStatus(for:), and if it were not granted, I could request it with CKContainer.default().requestApplicationPermission. Both of those functions (and several others that i was using in my app) now pop up with the message: 'requestApplicationPermission' was deprecated in iOS 17.0: No longer supported. Please see Sharing CloudKit Data with Other iCloudUsers. Unfortunately, I have found no alternate way to get the user identity in the Documentation, although it is a fairly large section and it's possible I am overlooking it. Is there a way to display the user's name components?
1
0
477
Jul ’23
SwiftData cloud data update in real time?
Hey, I've been working with SwiftData for a while now and I'm currently in the process of adding iCloud functionality to my program. Everything works fine, but the data update only after running the app twice or restarting it twice in the simulator. It would be better if this could be done in real time or at the push of a button. Does anyone have an idea how to implement this? The devices send a message in the background (that there is an update) or? Can you access it somehow and the @Query update?
0
0
417
Jul ’23
Potential problem with synching users' private CloudKit with NSPersistentCloudKitContainer
Imagine I have a game with new levels every day. Users play my game and their progress is saved in Core Data, which is then synchronized with CloudKit via NSPersistentCloudKitContainer. Users' progress is about 500Kb for each level/day. That's 5 Mb in 10 days. Or 182 Mb in a year. If the user plays my game for a year, gets a new iPhone, and installs my app again — will the NSPersistentCloudKitContainer eventually download all 182 Mb of users' data!?
1
0
416
Jul ’23
How to fetch ckWebAuthToken?
I am trying to make CloudKit Web service work by following the Apple Documentation at https://developer.apple.com/library/archive/documentation/DataManagement/Conceptual/CloudKitWebServicesReference/SettingUpWebServices.html I am able to get the redirect URL from curl --location 'https://api.apple-cloudkit.com/database/1/iCloud.Wasiq.Migraine/development/private/users/current?ckAPIToken=b440efde65bb8c1f45464598470f4cc73977f2c10d6c40587588ec9f1c1c56f0' Now, with the redirect URL, if I login with Apple ID, I am expecting ckWebAuthToken Documentations says If you did not specify a custom URL when creating the API token, register an event listener with the window object to be notified when the user signs in. window.addEventListener('message', function(e) { console.log(e.data.ckWebAuthToken);}) Here's a complete SwiftUI working project to reproduce the issue import SwiftUI import UIKit import WebKit struct ContentView: View { @State private var loadWeb = false @State private var url = "" var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundColor(.accentColor) Text("Hello, world!") .onTapGesture { var request = URLRequest(url: URL(string: "https://api.apple-cloudkit.com/database/1/iCloud.Wasiq.Migraine/development/private/users/current?ckAPIToken=b440efde65bb8c1f45464598470f4cc73977f2c10d6c40587588ec9f1c1c56f0")!,timeoutInterval: Double.infinity) request.httpMethod = "GET" let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data else { print(String(describing: error)) return } do { let res = try JSONDecoder().decode(Root.self, from: data) print("Getting URL") self.url = res.redirectURL self.loadWeb = true print(res.redirectURL) } catch let error { print(error) } } task.resume() } if(!loadWeb){ Spacer() } else{ WebView(url: $url) } } .padding() } } struct Root: Codable { let redirectURL: String} struct WebView: UIViewRepresentable { @Binding var url: String func makeCoordinator() -> WebView.Coordinator { Coordinator(self) } func makeUIView(context: Context) -> WKWebView { let config = WKWebViewConfiguration() let source = "window.addEventListener('message', function(e){ window.webkit.messageHandlers.logging.postMessage(e.data); })" let script = WKUserScript(source: source, injectionTime: .atDocumentStart, forMainFrameOnly: false) config.userContentController.addUserScript(script) config.userContentController.add(context.coordinator, name: "logging") let view = WKWebView(frame: UIScreen.main.bounds, configuration: config) view.navigationDelegate = context.coordinator view.load(URLRequest(url: URL(string: url)!)) return view } func updateUIView(_ uiView: WKWebView, context: Context) { // you can access environment via context.environment here // Note that this method will be called A LOT } class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler { func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { print("message: \(message.body)") // and whatever other actions you want to take } let parent: WebView init(_ parent: WebView) { self.parent = parent } }} When I tap on "Hello, World", the WebView gets loaded and asks the user to Sign in with Apple ID. After logging in, I do not see the ckWebAuthToken getting printed Instead I see the following output message: SOAuthorizationDidStart message: { authorization = { "grant_code" = "ce619474218c0485182af8cf019684d2e.0.sruq.i5r0nMCZIKVEBma6p6FE5Q"; "id_token" = ""; state = "auth-sznjvrn0-6svd-pw2c-lwfy-47rd7n64"; }; event = AppSSOTakeoverDidComplete; user = { };} message: { event = WidgetBridgeComplete; state = "auth-sznjvrn0-6svd-pw2c-lwfy-47rd7n64";}
1
0
387
Aug ’23
CloudKit Stopped Syncing after adding a new Attribute
My App is in the App Store, and synced well between iOS devices with the same iCloud account. But after adding a new attribute to an entity 2 weeks ago, the CloudKit stopped syncing. I checked the Cloudkit console, and can't find the new attribute there! I don't know Why. Actually this attribute already works well in the newest version of my App downloaded form App store. Then I chose to deploy schema changes, but there are no changes to deploy! So how to deploy the new change? and how to make the iCloud syncing work again? Thanks!
2
0
629
Jul ’23
How to set Custom name an iCloud container?
In the application iCloud integration but in the container, it displays the name of the bundle that owns the container. Configuration iCloud capability from developer account Enable iCloud capability from Xcode Added keys and value into info.plist file as below <key>NSUbiquitousContainers</key> <dict> <key>iCloud.com.example.applepaydemo</key> <dict> <key>NSUbiquitousContainerName</key> <string>Apple Demo</string> <key>NSUbiquitousContainerIsDocumentScopePublic</key> <true/> <key>NSUbiquitousContainerSupportedFolderLevels</key> <string>Any</string> </dict> </dict> Issue: It displays applepaydemo name of container not Apple Demo in iCloud Manage Account Storage
0
0
408
Aug ’23
Cloudkit data merge got duplicate
Hi, developer I have face the duplicate issue while using cloudkit. I am using registration app. I use cloudkit for generate UHID also. Is cloudkit is good to generate UHID. My problem, Cloudkit automatically sync the data in background at the time user create new reg. Eg: Cloudkit had 20 data but in local it insert 11 data and is in progress at the user create new one, i fetch latest UHID and i get 11 at the time i get the duplicate. I use the deduplicate code also, but some times not helpful also if two user get reg data at the same time it get conflict.
0
0
381
Aug ’23
Save object to shared database
Maybe I'm going about this completely the wrong way but I've got two stores loaded in my app: private and shared. I've got zone-wide sharing enabled and I can update records that exist in the shared database (on the participant device), and see updates sync when changed by the owner. However, is it possible to save a new object specifically to the shared database as the participant? If I create a new object in my managed object context it saves it to the private database. Can provide code if needed but it's more conceptual at this stage.
1
0
669
Aug ’23
SwiftData CloudKit integration requires that all attributes be optional, or have a default value set
After install XCode 15 beta 6: @Model class WordResult { var text = "" var translation:[String] = [] init(){ } } got this error: Variable 'self._$backingData' used before being initialized so I changed to : @Model class WordResult { var text:String var translation:[String] init(){ self.text = "" self.translation = [] } } Then got this: CloudKit integration requires that all attributes be optional, or have a default value set It seems it can not work with cloudkit now.
5
3
1.6k
Aug ’23
cannot push coredata records to cloudkit
coredata pushed schema to cloudkit only for those entities for which I created records. But the record data did not get pushed. I set recordName as Queryable and modifiedTimestamp as both Queryable and sortable. Query does not show the records. I look at Xcode console gives this output for one of the entities that got pushed to cloudkit : CoreData: debug: CoreData+CloudKit: -[PFCloudKitSerializer newCKRecordsFromObject:fullyMaterializeRecords:includeRelationships:error:](575): Serializer has finished creating record: <CKRecord: 0x13f40f920; recordType=CD_Contact, recordID=26809600-B329-4C17-B3E1-6EA5FC177F7C:(com.apple.coredata.cloudkit.zone:__defaultOwner__), values={ "CD_contact" = "26809600-B329-4C17-B3E1-6EA5FC177F7C"; "CD_contactEmail_ckAsset", "CD_contact", "CD_contactEmail", "<CKRecord: 0x13f40f920; recordType=CD_Contact, recordID=26809600-B329-4C17-B3E1-6EA5FC177F7C:(com.apple.coredata.cloudkit.zone:__defaultOwner__), recordChangeTag=5, values={\n \"CD_email\" = Email;\n \"CD_entityName\" = Contact;\n \"CD_firstName\" = V;\n \"CD_imageName\" = \"{ length=20834, sha256=d582bd2ccc7d93138b3a5ad4799443152860268e34f48ace54a0708f3e2f3aba }\";\n \"CD_lastName\" = R;\n \"CD_phone\" = 2;\n \"CD_screenName\" = Vr;\n \"CD_userRating\" = \"*****\";\n \"CD_userType\" = Household;\n}>", Also schema for some other entities that do not have any core data records did not get pushed to CloudKit. I thought the entire coredata schema should get pushed along with the records. Looks like it is pushing those entities that have some records but without pushing data. I reset the cloudkit environment and tried again, but issue is not resolved. Also the AppDelegate never gets called. I thought the line below should have called AppDelegate @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate: AppDelegate Cross referenced persistenceController in AppDelegate. That did not help either Code listed below. Please let me know how to fix the above two issues? main struct GreenApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate: AppDelegate static var fcmToken: String? let gcmMessageIDKey = "gcm.Message_ID" let persistenceController = PersistenceController.shared var body: some Scene { WindowGroup { ContentView() .environment(\.managedObjectContext, persistenceController.container.viewContext) } } } struct PersistenceController { static let shared = PersistenceController() static var preview: PersistenceController = { let result = PersistenceController(inMemory: true) let viewContext = result.container.viewContext // for _ in 0..<10 { // let newItem = Item(context: viewContext) // newItem.timestamp = Date() // } do { try viewContext.save() } catch { // Replace this implementation with code to handle the error appropriately. // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. let nsError = error as NSError fatalError("Unresolved error \(nsError), \(nsError.userInfo)") } return result }() let container: NSPersistentCloudKitContainer init(inMemory: Bool = false) { container = NSPersistentCloudKitContainer(name: "Green") if inMemory { container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") } container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { // Replace this implementation with code to handle the error appropriately. // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. fatalError("Unresolved error \(error), \(error.userInfo)") } }) container.viewContext.automaticallyMergesChangesFromParent = true container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy // external changes trumping in-memory changes. } } Appdelegate code: class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate, ObservableObject { static var fcmToken: String? let gcmMessageIDKey = "gcm.Message_ID" let persistenceController = PersistenceController.shared func applicationDidFinishLaunching(_ application: UIApplication) { do { // Use the container to initialize the development schema. try persistenceController.container.initializeCloudKitSchema(options: []) } catch { // Handle any errors. fatalError("###\(#function): failed to load persistent stores: \(error)") } if #available(iOS 10.0, *) { // For iOS 10 display notification (sent via APNS) UNUserNotificationCenter.current().delegate = self let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] UNUserNotificationCenter.current().requestAuthorization(options: authOptions, completionHandler: { granted, error in }) } else { let settings: UIUserNotificationSettings = UIUserNotificationSettings(types:[.alert, .badge, .sound], categories: nil) application.registerUserNotificationSettings(settings) } DispatchQueue.main.async { application.registerForRemoteNotifications() } } }
2
0
646
Aug ’23
Can I access CloudKit's metadata fields with NSPersistentCloudKitContainer?
I've got a simple Core Data Entity that is synchronized with CloudKit via NSPersistentCloudKitContainer. I can read my local fields, but how can I read fields like "Created" & "Modified" from CloudKit? Do I have to add them to my Core Data model and populate them myself? P.S. In his fantastic WWDC talk "Using Core Data with CloudKit", at around 21:40, Nick Gillet talks about how Core Data entities in the CloudKit store are prefixed with "CD_" to separate the things that it manages from the ones CloudKit implements. Then he says: "You wouldn't believe how many people add modify date to their CKRecord". Like it's something redundant.
0
0
405
Aug ’23
Using observableobject in a different View
Hello, I want to use this observableobject that I made in SavingMovieView in MovieView How do I do this...? import SwiftUI import CloudKit struct MovieView: View { @State var showingSavingMovieSheet:Bool = false var body: some View { NavigationView{ ZStack(alignment: .bottomTrailing){ //the list of movies List{ //ForEach(vm.movies) { movies in //} //Your Name Block NavigationLink { // } label: { VStack{ Image("your name") .resizable() .aspectRatio(contentMode: .fill) .cornerRadius(20) Text("Your Name") .fontWeight(.bold) .font(.system(size:20)) } .padding() .background(Image("beige")) } //notting hill block NavigationLink { NottingHillView() } label: { VStack{ Image("notting hill") .resizable() .aspectRatio(contentMode: .fill) .cornerRadius(20) Text("Notting Hill") .fontWeight(.bold) .font(.system(size:20)) } .background(Image("beige")) .padding() } //notting hill block NavigationLink { //Love_OtherDrugsView() } label: { VStack{ Image("love and other drugs") .resizable() .aspectRatio(contentMode: .fill) .cornerRadius(20) Text("Love & Other Drugs") .fontWeight(.bold) .font(.system(size:20)) } .background(Image("beige")) .padding() } } .scrollContentBackground(.hidden) .background(Image("beige")) Button { showingSavingMovieSheet.toggle() } label: { Image(systemName: "plus.circle.fill") .font(.system(size: 70)) .foregroundColor(.accentColor) .shadow(color: .gray, radius: 0.2, x: 1, y: 1) } .padding() .sheet(isPresented: $showingSavingMovieSheet) { SavingMovieView(vm: SavingMovieViewModel(container: CKContainer.default())) .presentationDetents([.fraction(0.5)]) } } .edgesIgnoringSafeArea(.bottom) .toolbar { ToolbarItem(placement: .principal){ Text("Movies") .font(Font.custom("Titan One",size:50)) .bold() .foregroundColor(Color.accentColor) } } } } } struct MovieView_Previews: PreviewProvider { static var previews: some View { MovieView() } } struct SavingMovieView: View { //making an object from the viewModel @StateObject private var vm: SavingMovieViewModel @State private var title: String = "" @State private var director: String = "" @State private var stars: String = "" @State private var review: String = "" @Environment(\.dismiss) var dismiss init(vm: SavingMovieViewModel){ _vm = StateObject(wrappedValue: vm) } var body: some View { VStack{ Text("Add movie") .bold() .foregroundColor(Color.accentColor) .font(Font.custom("Titan One",size:50)) TextField("Movie Title", text: $title) .textFieldStyle(.roundedBorder) TextField("Director Name", text: $director) .textFieldStyle(.roundedBorder) TextField("Number of rating stars", text: $stars) .textFieldStyle(.roundedBorder) TextField("Description", text: $review) .textFieldStyle(.roundedBorder) Button { vm.saveMovie(title: title, director: director, stars: stars, review: review) dismiss() } label: { Text("Save") } } .padding() } } struct SavingMovieView_Previews: PreviewProvider { static var previews: some View { SavingMovieView(vm: SavingMovieViewModel(container: CKContainer.default())) } }
2
0
456
Aug ’23
AppAccountToken is missing
Hello I've problem with transaction payload. If I receive POST App Store notification v2 to my server. In the decoded transaction body is missing appAccountToken field. In the iOS app I've just set token like this: let result = try await product.purchase(options: [ .appAccountToken(UUID.encodeIntAsUUID(Auth.shared.user.idUser)), .simulatesAskToBuyInSandbox(true) ]) Where is the problem?
0
0
568
Aug ’23
Cloudkit saving error
Hello, I recently started learning Swift and now I'm using Cloudkit to store user information. I kinda have no idea what I'm doing but I watched this youtube tutorial to save user data and display it in UI instantly with DispatchQueue.main.async but it keeps throwing me an error, saying "No exact matches in call to instance method 'save'" What I want to do is I want users to save a new record and I want this record to be updated instantly and be displayed on the screen. How could I fix this? import Foundation import CloudKit enum RecordType:String { case movie = "Movie" } class SavingMovieViewModel : ObservableObject{ private var database :CKDatabase private var container : CKContainer @Published var movies: [SavingMovieModel] = [] init(container: CKContainer){ self.container = container self.database = container.publicCloudDatabase } func saveMovie(title:String, director: String, stars:String, review: String){ let record = CKRecord(recordType: RecordType.movie.rawValue) let movie = Movie(theTitle: title, theDirector: director, theStars: stars, theReview: review) record.setValuesForKeys(movie.toDictionary()) // saving self.database.save(record) { newRecord, error in. //<-- here is where the error is :( if let error = error{ print(error) } else{ if let newRecord = newRecord{ //<-- this bit is the problem. i need the new record added to be displayed instantly if let movie = Movie.fromRecord(newRecord){ DispatchQueue.main.async { self.movies.append(SavingMovieModel(Movie: movie)) } } } } } } func whatMovies(){ //creating an array of movies var movies: [Movie] = [] let query = CKQuery(recordType: RecordType.movie.rawValue, predicate: NSPredicate(value: true)) database.fetch(withQuery: query) { result in switch result{ case.success(let result): result.matchResults.compactMap{$0.1} .forEach{ switch $0 { case.success(let record): if let movie = Movie.fromRecord(record){ movies.append(movie) } case.failure(let error): print(error) } } DispatchQueue.main.async { self.movies = movies.map(SavingMovieModel.init) } case.failure(let error): print(error) } } } } struct SavingMovieModel{ let movie: Movie var movieId :CKRecord.ID?{ movie.movieId } var title:String{ movie.title } var director:String{ movie.director } var stars:String{ movie.stars } var review:String{ movie.review } } This is the Movie struct for Movie objects import Foundation import CloudKit struct Movie{ var movieId: CKRecord.ID? var title:String var director:String var stars:String var review:String init(movieId: CKRecord.ID? = nil, theTitle:String, theDirector:String, theStars:String, theReview:String){ self.title = theTitle self.director = theDirector self.stars = theStars self.review = theReview self.movieId = movieId } func toDictionary() -> [String:Any]{ return ["title": title, "director" :director, "stars":stars, "review": review] } static func fromRecord(_ record :CKRecord) -> Movie? { guard let title = record.value(forKey:"title") as? String, let director = record.value(forKey:"director") as? String, let stars = record.value(forKey:"stars") as? String, let review = record.value(forKey:"review") as? String else{ return nil } return Movie(movieId: record.recordID, theTitle: title, theDirector: director, theStars: stars, theReview: review) } }
3
0
723
Aug ’23
"This NSPersistentStoreCoordinator has no persistent stores", despite setting up all capabilities
Hi guys, First of all, I'm sorry if this is the wrong place to post this. I'm in the last steps of my task manager app: getting the tasks to sync between devices. However, I get the error "This NSPersistentStoreCoordinator has no persistent stores (unknown). It cannot perform a save operation." What does this error exactly mean? My container is initialised so it should have a persistent store, right? I've also enabled all the proper capabilities I'm pretty sure (eg, I've enabled CloudKit, created a container, enabled background fetch and remote notifications.) Here is the code for my data controller: import CoreData import Foundation class DataController: ObservableObject { let container = NSPersistentCloudKitContainer(name: "TaskDataModel") init() { guard let description = container.persistentStoreDescriptions.first else { fatalError("Container descriptions not loaded") } description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy container.viewContext.automaticallyMergesChangesFromParent = true container.loadPersistentStores { description, error in if let error = error { print("Core Data failed to load: \(error.localizedDescription)") } } } } Here is TaskManMain: @main struct TaskManApp: App { @StateObject private var dataController = DataController() var body: some Scene { WindowGroup { MainView() .environment(\.managedObjectContext, dataController.container.viewContext) } } } Here is the full repo if y'all are interested: https://github.com/aabagdi/TaskMan Thanks for any help!
1
0
832
Aug ’23
Cloudkit Many to Many relationship not updating on public record with full permissions when updated by user other than creator
I have narrowed my problem down to the many to many relationship between user and group record types. When a user transfers ownership of a group the new admin can change things like privacy (a field) but still only the original owner can leave or remove others. The new admin's use of remove user does nothing and no users can leave besides the creator. All security perms are enabled, and no permission not granted errors arise. I simply end up with two unsynced devices where one user observes themselves as having left, and the other that never will observe it. I can get around this a long way but don't really see why I should have to.
0
0
349
Aug ’23
Usage of CKQueryOperation.recordMatchedBlock and .queryResultBlock
Anyone know the correct usage for CKQueryOperation.recordMatchedBlock and .queryResultBlock? Xcode is telling me to use them as the old .recordFetchedBlock and .queryCompletionBlock are deprecated, but there isn't any documentation to say how they should be used. ChatGPT, Bard etc aren't able to provide a correct answer either: specifically, I need to convert the following to use those methods: operation.recordFetchedBlock = { record in // Convert CKRecord to Core Data object and save to Core Data self.saveToCoreData(record: record) } operation.queryCompletionBlock = { (cursor, error) in // Handle potential errors if let error = error { print("Error syncing first of month records: \(error)") } if let cursor = cursor { // There are more records to fetch for this category, continue fetching self.continueSyncing(cursor: cursor, completion: completion) } else { // Done syncing this category, move to the next sync task completion() } }
1
0
492
Aug ’23
Converting a .swiftpm app to a .xcodeproj-based one?
I've decided I want my app, which has been shipped to the App Store, to support CloudKit, but it's a .swiftpm app (so I could work on it on the go on an iPad and Swift Playgrounds). I've taken a half-hearted stab at it (there's more pressing stuff to work on and this is a nice to have for the moment), but is there a way to set up a new workspace in Xcode where I have two targets: a .swiftpm version of the app and a .xcodeproj app so I can enable CloudKit for my app and also ship it to the App Store with the same identifier?
0
1
550
Aug ’23