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

NSPersistentCloudKitContainer Import failed (incomprehensible archive)
I am using NSPersistentCloudKitContainer and I decided to add a property to an entity. I accidentally ran try! container.initializeCloudKitSchema(options: []) while using the production container in Xcode (com.apple.developer.icloud-container-environment) which throw a couple of errors and created some FAKE_ records in my production container. So I changed to my development container and ran the try! container.initializeCloudKitSchema(options: []) and now it succeeded. After that I cleaned up the FAKE_ records scattered in production container but in Xcode when I'm running I now get these logs in the console (and I can't seem to get rid of them): error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _importFinishedWithResult:importer:](1398): <PFCloudKitImporter: 0x300cc72c0>: Import failed with error: Error Domain=NSCocoaErrorDomain Code=4864 "*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x53, 0x6f, 0x6d, 0x65, 0x20, 0x73, 0x61, 0x6d)" UserInfo={NSDebugDescription=*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x53, 0x6f, 0x6d, 0x65, 0x20, 0x73, 0x61, 0x6d)} error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate recoverFromError:](2310): <NSCloudKitMirroringDelegate: 0x302695770> - Attempting recovery from error: Error Domain=NSCocoaErrorDomain Code=4864 "*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x53, 0x6f, 0x6d, 0x65, 0x20, 0x73, 0x61, 0x6d)" UserInfo={NSDebugDescription=*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x53, 0x6f, 0x6d, 0x65, 0x20, 0x73, 0x61, 0x6d)} error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _recoverFromError:withZoneIDs:forStore:inMonitor:](2620): <NSCloudKitMirroringDelegate: 0x302695770> - Failed to recover from error: NSCocoaErrorDomain:4864 Recovery encountered the following error: (null):0 error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate resetAfterError:andKeepContainer:](610): <NSCloudKitMirroringDelegate: 0x302695770> - resetting internal state after error: Error Domain=NSCocoaErrorDomain Code=4864 "*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x53, 0x6f, 0x6d, 0x65, 0x20, 0x73, 0x61, 0x6d)" UserInfo={NSDebugDescription=*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x53, 0x6f, 0x6d, 0x65, 0x20, 0x73, 0x61, 0x6d)} error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _requestAbortedNotInitialized:](2198): <NSCloudKitMirroringDelegate: 0x302695770> - Never successfully initialized and cannot execute request '<NSCloudKitMirroringExportRequest: 0x303a52d00> 548CB420-E378-42E5-9607-D23E7A2A364D' due to error: Error Domain=NSCocoaErrorDomain Code=4864 "*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x53, 0x6f, 0x6d, 0x65, 0x20, 0x73, 0x61, 0x6d)" UserInfo={NSDebugDescription=*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x53, 0x6f, 0x6d, 0x65, 0x20, 0x73, 0x61, 0x6d)}
3
1
401
Dec ’24
SwiftData and async functions
Hello, I recently published an app that uses Swift Data as its primary data storage. The app uses concurrency, background threads, async await, and BLE communication. Sadly, I see my app incurs many fringe crashes, involving EXC_BAD_ACCESS, KERN_INVALID_ADDRESS, EXC_BREAKPOINT, etc. I followed these guidelines: One ModelContainer that is stored as a global variable and used throughout. ModelContexts are created separately for each task, changes are saved manually, and models are not passed around. Threads with different ModelContexts might manipulate and/or read the same data simultaneously. I was under the impression this meets the usage requirements. I suspect perhaps the issue lies in my usage of contexts in a single await function, that might be paused and resumed on a different thread (although same execution path). Is that the case? If so, how should SwiftData be used in async scopes? Is there anything else particularly wrong in my approach?
3
0
829
Dec ’24
File Provider Extension trouble
Hi everyone, I am a beginner in iOS/Swift programming. I'm trying to develop a mobile application that allows to mount a network drive in the iphone Files application via the WebDav protocol. I saw on the internet that WebDav is no longer implemented in iOS because considered deprecated by apple. To accomplish this task, I decided to separate responsibilities as follows: Framework: WebDav (responsible for communication with the WebDav server) FileProviderExtension: FileBridge (Responsible for bridging the gap between the WebDav Framework and the iOS Files app) Main App I also have an AppGroup that includes the main application and the fileproviderextension Initially, to measure the feasibility and complexity of this task, I'd like to make a simplistic version that simply displays the files on my drive in the Files app, without necessarily being able to interact with them. FileProviderExtension.swift: import FileProvider import WebDav class FileProviderExtension: NSObject, NSFileProviderReplicatedExtension { private var webDavService: WebDavService? required init(domain: NSFileProviderDomain) { super.init() self.webDavService = WebDavService(baseURL: URL(string: "https://www.mydrive.com/drive")!) } func invalidate() { // TODO: cleanup any resources } func item(for identifier: NSFileProviderItemIdentifier, request: NSFileProviderRequest, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) -> Progress { let progress = Progress(totalUnitCount: 1) Task { do { if let items = try await webDavService?.propfind(path: identifier.rawValue, depth: 1), let item = items.first(where: { $0.itemIdentifier == identifier }) { completionHandler(item, nil) } else { completionHandler(nil, NSError(domain: NSCocoaErrorDomain, code: NSFileNoSuchFileError, userInfo: nil)) } } catch { completionHandler(nil, error) } } return progress } func fetchContents(for itemIdentifier: NSFileProviderItemIdentifier, version requestedVersion: NSFileProviderItemVersion?, request: NSFileProviderRequest, completionHandler: @escaping (URL?, NSFileProviderItem?, Error?) -> Void) -> Progress { let progress = Progress(totalUnitCount: 1) Task { do { guard let service = webDavService else { throw WebDavError.invalidResponse } let data = try await service.get(fileAt: itemIdentifier.rawValue) let tempURL = FileManager.default.temporaryDirectory.appendingPathComponent(itemIdentifier.rawValue) try data.write(to: tempURL) completionHandler(tempURL, nil, nil) } catch { completionHandler(nil, nil, error) } } return progress } func createItem(basedOn itemTemplate: NSFileProviderItem, fields: NSFileProviderItemFields, contents url: URL?, options: NSFileProviderCreateItemOptions = [], request: NSFileProviderRequest, completionHandler: @escaping (NSFileProviderItem?, NSFileProviderItemFields, Bool, Error?) -> Void) -> Progress { // TODO: a new item was created on disk, process the item's creation completionHandler(itemTemplate, [], false, nil) return Progress() } func modifyItem(_ item: NSFileProviderItem, baseVersion version: NSFileProviderItemVersion, changedFields: NSFileProviderItemFields, contents newContents: URL?, options: NSFileProviderModifyItemOptions = [], request: NSFileProviderRequest, completionHandler: @escaping (NSFileProviderItem?, NSFileProviderItemFields, Bool, Error?) -> Void) -> Progress { // TODO: an item was modified on disk, process the item's modification completionHandler(nil, [], false, NSError(domain: NSCocoaErrorDomain, code: NSFeatureUnsupportedError, userInfo:[:])) return Progress() } func deleteItem(identifier: NSFileProviderItemIdentifier, baseVersion version: NSFileProviderItemVersion, options: NSFileProviderDeleteItemOptions = [], request: NSFileProviderRequest, completionHandler: @escaping (Error?) -> Void) -> Progress { // TODO: an item was deleted on disk, process the item's deletion completionHandler(NSError(domain: NSCocoaErrorDomain, code: NSFeatureUnsupportedError, userInfo:[:])) return Progress() } func enumerator(for containerItemIdentifier: NSFileProviderItemIdentifier, request: NSFileProviderRequest) throws -> NSFileProviderEnumerator { return FileProviderEnumerator(enumeratedItemIdentifier: containerItemIdentifier, service: webDavService) } } Here's the code I use to initialize my domain in the main app files: fileprivate func registerFileProviderDomain() { let domainIdentifier = NSFileProviderDomainIdentifier("FileProviderExtension Bundle Identifier") let domain = NSFileProviderDomain(identifier: domainIdentifier, displayName: "My Drive") NSFileProviderManager.add(domain) { error in NSFileProviderManager.add(domain) { error in if let error = error { print("Error cannot add domain file provider : \(error.localizedDescription)") } else { print("Success domain file provider added") } } } I can't get rid of the Error : Error cannot add domain file provider : The operation couldn’t be completed. Invalid argument. I don't know what I'm missing Please help me understand
1
0
753
Dec ’24
removing the beta developer tab from your phone settings
Hello, on every Apple device, iPhone/Watch I have the option to install developer beta versions. I would like to unsubscribe from developer beta versions - not have them in settings. I know that developer beta is assigned to my iCloud account. After logging out and restoring factory settings, the tab disappears. When I log into my iCloud account, it appears everywhere. I did not sign up for developer beta. How do I remove it?
4
0
759
Dec ’24
iCloudKit Unable to Deploy Container to Production Environment
When attempting to deploy schema changes in the iCloudKit Database by clicking the Deploy Schema Changes button, a Confirm Deployment dialog appears, showing an error: “Internal error”. The following error details were observed in the JavaScript console: • description: “The request has failed due to an error.” • headers: undefined • message: “Known response error: The request has failed due to an error.” • result: • code: 400 • detailedMessage: undefined • message: “bad-request” • reason: “Internal error” • redirectUrl: undefined • requestUuid: “0c5b4af2-15c9-425f-87ea-************” • retryAfterSeconds: undefined
2
0
713
Dec ’24
Jak usunąć zakładkę Uaktualnienia Beta z urządzeń?
Witam, na każdym urządzeniu Apple, iPhone’a/Watch mam możliwość instalować wersje beta developer. chciałbym wypisać się z wersji beta developer - nie mieć ich w ustawieniach. wiem że beta developer jest przypisana do mojego konta iCloud. po wylogowaniu się i przywróceniu ustawień fabrycznych, zakładka znika. gdy loguje się na konto iCloud pojawia Się wszędzie. nie zapisałem sie do developer bety. jak to usunąc?
1
0
634
Dec ’24
caches directory counts towards app storage?
throughout all of Foundation's URL documentation, its called out in multiple places that data stored inside an app sandox's caches directory doesn't count towards data and documents usage in the settings app but in practice, it looks like storing data there does in fact count towards documents & data for the app i'm trying to understand if the docs are wrong, if theres a bug in the settings app, or if this is a mistake on my part
3
0
673
Dec ’24
Issues during CloudKit record sharing
I am trying to implement record sharing in my project, but when I try to copy the link on the UICloudSharingController, the sheet closes and the link doesn't get copied. My CloudKitManager function: public func shareTeam(_ team: Team) -> AnyPublisher<CKShare, Error> { Future { [weak self] promise in guard let self = self else { promise(.failure(CloudKitError.unknown)) return } let record = team.toCKRecord() let share = CKShare(rootRecord: record) share[CKShare.SystemFieldKey.title] = "Join \(team.name)" as CKRecordValue share.publicPermission = .readWrite let operation = CKModifyRecordsOperation(recordsToSave: [record, share], recordIDsToDelete: nil) operation.savePolicy = .ifServerRecordUnchanged operation.qualityOfService = .userInitiated operation.modifyRecordsResultBlock = { result in switch result { case .success: promise(.success(share)) case .failure(let error): promise(.failure(error)) } } self.privateDatabase.add(operation) } .eraseToAnyPublisher() } ViewModel function: func shareTeam() { guard let selectedTeam = selectedTeam else { return } CloudKitManager.shared.shareTeam(selectedTeam) .receive(on: DispatchQueue.main) .sink { [weak self] completion in switch completion { case .finished: break case .failure(let error): self?.didError = true self?.error = error } } receiveValue: { share in let sharePresenter = SharePresenter( share: share, container: CloudKitManager.shared.container, teamName: selectedTeam.name, rootRecord: selectedTeam.toCKRecord() ) sharePresenter.presentShareSheet() } .store(in: &cancellables) }
1
0
608
Dec ’24
CloudKit Dashboard error "Failed to execute query"
Something has caused my CloudKit queries to fail. On the dashboard I get an error message "Failed to execute query" when I try to "SORT BY" a field. The field is listed under Indexes as "sortable". For a different field, when I enter the field under "FILTER BY", and before I tap "Query", I get "No results". That field is listed under the Indexes as "queryable". It used to work fine. I have described this further, with screenshots at FB16114560
1
0
332
Dec ’24
Significant increase in 'Other' CloudKit errors
Looking at my CloudKit Telemetry console I noticed a significant increase in 'Other' errors recently. These errors are impacting user experience and I really don't know how to better understand the issues that may be occurring due to the "other" category. If I query the logs for "other" errors, only 2 results show up for the week. There are 2500+ errors in the telemetry graph (see attached). Is anyone else experiencing this or does anyone have a suggestion on how I can better understand this issue? Thank you!
0
0
341
Dec ’24
Core Data `context.performAndWait` in an actor
Hello. I am re-writing our way of storing data into Core Data in our app, so it can be done concurrently. The solution I opted for is to have a singleton actor that takes an API model, and maps it to a Core Data object and saves it. For example, to store an API order model, I have something like this: func store( order apiOrder: APIOrder, currentContext: NSManagedObjectContext? ) -&gt; NSManagedObjectID? { let context = currentContext ?? self.persistentContainer.newBackgroundContext() // … } In the arguments, there is a context you can pass, in case you need to create additional models and relate them to each other. I am not sure this is how you're supposed to do it, but it seemed to work. From what I've understood of Core Data and using multiple contexts, the appropriate way use them is with context.perform or context.performAndWait. However, since my storage helper is an actor, @globalActor actor Storage2 { … }, my storage's methods are actor-isolated. This gives me warnings / errors in Swift 6 when I try to pass the context for to another of my actor's methods. let context = … return context.performAndWait { // … if let apiBooking = apiOrder.booking { self.store(booking: apiBooking, context: context) /* causes warning: Sending 'context' risks causing data races; this is an error in the Swift 6 language mode 'self'-isolated 'context' is captured by a actor-isolated closure. actor-isolated uses in closure may race against later nonisolated uses Access can happen concurrently */ } // … } From what I understand this is because my methods are actor-isolated, but the closure of performAndWait does not execute in a thread safe environment. With all this, what are my options? I've extracted the store(departure:context:) into its own method to avoid duplicated code, but since I can't call it from within performAndWait I am not sure what to do. Can I ditch the performAndWait? Removing that makes the warning "go away", but I don't feel confident enough with Core Data to know the answer. I would love to get any feedback on this, hoping to learn!
0
0
439
Dec ’24
Use CoreData alongside SwiftData for the "Sharing" feature in the app.
Hello! 😊 I currently manage an app called MoneyKeeper that uses SwiftData for its data storage framework. Many users have requested a "sharing" feature, but unfortunately, SwiftData does not yet support this functionality, and it’s unclear when it will. 😭 Initially, I considered using CloudKit and CKSyncEngine to implement quick synchronization and sharing. However, due to the complexity of the current data model’s relationships, modeling it with CloudKit’s schema alone seemed overly complicated and likely to introduce bugs. As a result, I’ve decided to implement the sharing feature using CoreData and CloudKit. My plan to avoid conflicts with SwiftData includes: Keeping the local storage locations for SwiftData and CoreData separate. Using entirely separate CloudKit containers for SwiftData and CoreData. I believe these measures will minimize potential issues, but I’m wondering if there’s anything else I should consider. Using both SwiftData (for the personal database) and CoreData (for the shared database) feels like it could lead to significant technical debt in the future, and I anticipate encountering even more challenges during actual implementation. I’d greatly appreciate your valuable insights on this matter. 🙏 The app MoneyKeeper, currently operated using SwiftData. https://apps.apple.com/app/id6514279917
1
0
727
Dec ’24
SwiftData + CKSyncEngine
Hi, I'm building a habit tracking app for iOS and macOS. I want to use up to date technologies, so I'm using SwiftUI and SwiftData. I want to store user data locally on device and also sync data between device and iCloud server so that the user could use the app conveniently on multiple devices (iPhone, iPad, Mac). I already tried SwiftData + NSPersistentCloudKitContainer, but I need to control when to sync data, which I can't control with NSPersistentCloudKitContainer. For example, I want to upload data to server right after data is saved locally and download data from server on every app open, on pull-to-refresh etc. I also need to monitor sync progress, so I can update the UI and run code based on the progress. For example, when downloading data from server to device is in progress, show "Loading..." UI, and when downloading finishes, I want to run some app business logic code and update UI. So I'm considering switching from NSPersistentCloudKitContainer to CKSyncEngine, because it seems that with CKSyncEngine I can control when to upload and download data and also monitor the progress. My database schema (image below) has relationships - "1 to many" and "many to many" - so it's convenient to use SwiftData (and underlying CoreData). Development environment: Xcode 16.1, macOS 15.1.1 Run-time configuration: iOS 18.1.1, macOS 15.1.1 My questions: 1-Is it possible to use SwiftData for local data storage and CKSyncEngine to sync this local data storage with iCloud? 2-If yes, is there any example code to implement this? I've been studying the "CloudKit Samples: CKSyncEngine" demo app (https://github.com/apple/sample-cloudkit-sync-engine), but it uses a very primitive approach to local data storage by saving data to a JSON file on disk. It would be very helpful to have the same demo app with SwiftData implementation! 3-Also, to make sure I don't run into problems later - is it okay to fire data upload (sendChanges) and download (fetchChanges) manually with CKSyncEngine and do it often? Are there any limits how often these functions can be called to not get "blocked" by the server? 4-If it's not possible to use SwiftData for local data storage and CKSyncEngine to sync this local data storage with iCloud, then what to use for local storage instead of SwiftData to sync it with iCloud using CKSyncEngine? Maybe use SwiftData with the new DataStore protocol instead of the underlying CoreData? All information highly appreciated! Thanks, Martin
3
0
1k
Dec ’24
Ongoing Issues with ModelActor in SwiftData?
After the problems with the ModelActor in iOS 18, it seemed like the ModelActor became more stable with iOS 18.1 and macOS 15.1. However, I’m still encountering many problems and crashes. I wanted to ask if these issues are related to my persistence layer architecture or if they’re still inherent to the ModelActor itself. I’ve generally followed the blog posts: https://fatbobman.com/en/posts/practical-swiftdata-building-swiftui-applications-with-modern-approaches/ and https://brightdigit.com/tutorials/swiftdata-modelactor/ and aim to achieve the following: I have a single DataProvider that holds the ModelContainer and uses it to configure and initialize a single DataHandler. These are created once at app launch and injected into the SwiftUI view hierarchy as EnvironmentObjects. Since I need to access the SwiftData models not only in SwiftUI but also indirectly in ViewModels or UIKit views, all read operations on the models should go through the DataProvider ( ModelContainrs MainContext), while all other CRUD operations are handled centrally via the single DataHandler (executed within a single ModelActor). Additionally, I want to monitor the entire container using another ModelActor, initialized in the DataProvider, which tracks changes to objects using TransactionHistory. I’ve managed to implement this to some extent, but I’m facing two main issues: ModelActor and Main Actor Requirement The ModelActor only updates SwiftUI views when initialized via the main context of the ModelContainer and therefore runs on the Main Actor. It would be ideal for this to work in the background, but the issue with the ModelActor that existed previously doesn’t seem to have been resolved in iOS 18.1/macOS 15.1—am I wrong about this? Frequent Crashes (more severe) Crashes occur, especially when multiple windows on macOS or iPadOS access the same DataHandler to update models. This often leads to crashes during read operations on models by a SwiftUI view, with logs like: Object 0x111f15480 of class _ContiguousArrayStorage deallocated with non-zero retain count 3. This object's deinit, or something called from it, may have created a strong reference to self which outlived deinit, resulting in a dangling reference. error: the replacement path doesn't exist: "/var/folders/gs/8rwdjczj225d1pj046w3d97c0000gn/T/swift-generated-sources/@__swiftmacro_12SwiftDataTSI3TagC4uuID18_PersistedPropertyfMa_.swift" Can't show file for stack frame : <DBGLLDBStackFrame: 0x34d28e170> - stackNumber:1 - name:Tag.uuID.getter. The file path does not exist on the file system: /var/folders/gs/8rwdjczj225d1pj046w3d97c0000gn/T/swift-generated-sources/@__swiftmacro_12SwiftDataTSI3TagC4uuID18_PersistedPropertyfMa_.swift This error usually happens when there are multiple concurrent accesses to the DataHandler/ModelActor. However, crashes also occur sporadically during frequent accesses from a single view with an error like "the replacement path doesn't exist." It also seems like having multiple ModelActors, as in this case (one for observation and one for data changes), causes interference and instability. The app appears to crash less frequently when the observer is not initialized, but I can’t verify this—it might just be a coincidence. My Question: Am I fundamentally doing something wrong with the ModelActors or the architecture of my persistence layer?
3
0
1.1k
Dec ’24