Core Data

RSS for tag

Save your application’s permanent data for offline use, cache temporary data, and add undo functionality to your app on a single device using Core Data.

Posts under Core Data tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

WidgetKit using CoreData background context
Hi, In our tests, especially when we tested the new widgets with interactions (introduced in iOS 17), we found that sometimes they can hang when fetching data from CoreData using background context. I realise that there is no reason to use background context in widgets, but in our case we were reusing logic and so there were multiple background contexts. I'm trying to find information about using background context in widgets, but I can't find it. Now we avoid using background context in widgets, but it would be interesting to know if the use of CoreData background context in widgets is not allowed or could it be a kind of bug? Perhaps this information would be useful to anyone trying to find the cause of widget hangs.
0
0
323
Jan ’24
iOS extensions - order of installation
Hi, I have a few extensions for my iOS app: Share Extension, Widget extensions, Notification Extensions, Today Extension, WatchKit app. My app and all the extensions share data by loading the same Core Data sqlite database from a shared folder. One problem I'm having with this setup is with a Core Data lightweight migration. On updating the app to the new database model, I would like my main app to first make a backup of the database before the migration runs. But one of the app extensions always seems to run before the main app, and ends up performing the lightweight migration on the database file before the main app has a chance to backup the database sqlite file. I can just prevent the lightweight migration from happening when an app extension loads the persistent store (and only do lightweight migrations from the main app), but it might end up in a situation with incompatible formats for the extension, so I'm looking for a sturdier solution. When an app is installed (or an update to the app is installed), is there a way to check and control the order of the extensions that is installed / loaded by the system? That would help control the problem.
0
0
390
Jan ’24
Core Data modifications not saved in two of three tables
I'm a bit lost because of a problem I never experienced before, however, I have a suspicion. I use Core Data for data storage and DB Browser for SQLite for inspecting the database running in the Simulator. Here's the relevant function where all Core Data handling happens: /** Creates a new ComposedFoodItem from the ComposedFoodItemViewModel. Creates the related FoodItem and the Ingredients. Creates all relationships. - Parameter composedFoodItemVM: The source view model. - Returns: A Core Data ComposedFoodItem; nil if there are no Ingredients. */ static func create(from composedFoodItemVM: ComposedFoodItemViewModel, generateTypicalAmounts: Bool) -> ComposedFoodItem? { debugPrint(AppDelegate.persistentContainer.persistentStoreDescriptions) // The location of the .sqlite file let moc = AppDelegate.viewContext // Create new ComposedFoodItem (1) let cdComposedFoodItem = ComposedFoodItem(context: moc) // No existing composed food item, therefore create a new UUID cdComposedFoodItem.id = UUID() // Fill data cdComposedFoodItem.amount = Int64(composedFoodItemVM.amount) cdComposedFoodItem.numberOfPortions = Int16(composedFoodItemVM.numberOfPortions) // Create the related FoodItem (2) let cdFoodItem = FoodItem.create(from: composedFoodItemVM, generateTypicalAmounts: generateTypicalAmounts) // Relate both (3) cdComposedFoodItem.foodItem = cdFoodItem // Add cdComposedFoodItem to composedFoodItemVM composedFoodItemVM.cdComposedFoodItem = cdComposedFoodItem // Save before adding Ingredients, otherwise this could lead to an NSInvalidArgumentException (4) try? moc.save() // Add new ingredients (5) if let cdIngredients = Ingredient.create(from: composedFoodItemVM) { cdComposedFoodItem.addToIngredients(NSSet(array: cdIngredients)) // Save new composed food item try? moc.save() // Return the ComposedFoodItem return cdComposedFoodItem } else { // There are no ingredients, therefore we delete it again and return nil moc.delete(cdComposedFoodItem) try? moc.save() return nil } } What the function does: Creates a new entry in table ComposedFoodItem Creates another new entry in another table FoodItem Relates both entries Saves the modifications (and as of here I can see both new entries in the DB with all relations created correctly) Creates another 1..n entries in a third table Ingredient and links these to the entry created in step 1 All this works fine, I can see all relations and entries in the database. Then I quit and restart the app. The entry created in step 2 is still there, but the entries created in steps 1 and 5 are gone, as well as the relationships (of course). My suspicion: I recently implemented a Core Data migration from Data Model version 1 ("EasyFPU") to version 2 ("EasyFPU 2"). In this migration, I have two custom migration policies for exactly the two tables, which are not stored. The migration policies are pretty simple (and identical for both tables): /** No Ingredient is created in the destination model, i.e., there will be no Ingredients */ override func createDestinationInstances(forSource sourceIngredient: NSManagedObject, in mapping: NSEntityMapping, manager: NSMigrationManager) throws { // Do nothing on purpose debugPrint("Not migrating Ingredient with ID: \((sourceIngredient as? Ingredient)?.id.uuidString ?? "unknown")") } And what I suspect is, that this migration policies are somehow called when restarting the app, but I have no idea why, because the migration has already happened before. If I set a breakpoint in the debugPrint line of the code snippet above, I actually never reach this breakpoint - as expected. Nevertheless are the two tables Ingredient and ComposedFoodItem empty after restart. My AppDelegate Core Data persistentContainer variable looks like this: lazy var persistentContainer: NSPersistentCloudKitContainer = { let container = NSPersistentCloudKitContainer(name: "EasyFPU") container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { fatalError("Unresolved error \(error), \(error.userInfo)") } }) return container }() I tried to replace "EasyFPU" with "EasyFPU 2", but this apparently is not the version, but the container name. Any idea? Thanks in advance!
0
0
205
Jan ’24
Saving images to core data runs of memory
I'm trying to do a mass conversion of images to data so it can be stored in core data. The conversion part works fine, and if I do it without updating core data it shows memory usage at less that 100MB If I update the core data object, it just keeps consuming memory until the app crashes. func updateLocalImages() { let fetchRequest: NSFetchRequest<Picture> = Picture.fetchRequest() fetchRequest.predicate = NSPredicate(format: "pictureName != \"\"") do { let pictures = try moc.fetch(fetchRequest) print("Picture Update Count: \(pictures.count)") for picture in pictures { let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) let path = paths[0] if let picName = picture.pictureName { let imagePath = path.appendingPathComponent(picName) if let uiImage = UIImage(contentsOfFile: imagePath.path) { if let imageData = uiImage.jpegData(compressionQuality: 1.0) { autoreleasepool { picture.pictureData = imageData print("Picture Updated") saveContext() } } } } } } catch { print("Fetching Failed") } } If I comment out the picture.pictureData = imageData line I don't get the memory issues. What's the correct way of going about this? There is an unknown number of images (mine current sits at about 5.5GB worth, 800+)
1
0
321
Jan ’24
GeometryReader cause FetchedResults object's view not updated after object's value changed.
Steps to reproduce: click any item in the list to get into its detail view click the + button to increase the count value of the item go back to the item list [ISSUE 1] the count value of the item is not updated in the list view now click the item you just operated to go back its detail view [ISSUE 2] the item's draft value is reverted back to the origin value (Or you can say it's the value displayed in the list view) If you remove the GeometryReader, it works normally, without that 2 issues. The Result I want: The list view's count value updated after going back to the list view. The draft value should be the same as the item at second entry after updating count. import SwiftUI import CoreData struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext @FetchRequest( sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)], animation: .default) private var items: FetchedResults<Item> var body: some View { NavigationView { List { ForEach(items) { item in // Not Work GeometryReader { geo in NavigationLink(destination: SubView(item: item)) { HStack { Text("\(item.timestamp!.ISO8601Format())") Spacer(minLength: 0) Text(String(item.count)) } } } // Works // NavigationLink(destination: SubView(item: item)) { // HStack { // Text("\(item.timestamp!.ISO8601Format())") // Spacer(minLength: 0) // Text(String(item.count)) // } // } } } } } } struct SubView: View { @ObservedObject var item: Item @State private var draft: TmpItem init(item: Item) { self.item = item self._draft = State(wrappedValue: TmpItem(count: Int(item.count))) } var body: some View { VStack { Text("\(item.timestamp!.ISO8601Format())") Text("item: \(item.count)") Text("draft: \(draft.count)") Button("+") { draft.count += 1 item.count = Int16(draft.count) try! viewContext.save() } .buttonStyle(.borderedProminent) } } @Environment(\.managedObjectContext) private var viewContext } struct TmpItem { var count: Int } #Preview { ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) } It's base on the defualt demo code from Xcode 15.1.0 for iOS app with core data. Added a count field (Int16) to the Item object.
1
0
339
Dec ’23
Help with Widget Configuration
Hello, I'm working on my first app. It's also my first encounter with App Intents. I have a data structure for events that has an ID (String), a name (String), a Date and an image (Data). The user can create them in the app and they are stored with CoreData. I wanted to have a widget that would allow the user to choose from their list of events and display that event in the widget. The list should appear in the widget configuration and it would be a list of the names and (if possible) the image. I think I have found how to access the information from the widget, but I cannot figure out how to have the list appear in the configuration. I have been following this guide: https://developer.apple.com/documentation/widgetkit/making-a-configurable-widget?utm_source=pocket_saves. But that one shows hardcoded elements in the list and I haven't been able to find how to have the list change in relation to the content of the app. This is what I have made so far in the AppIntent file: import WidgetKit import AppIntents import CoreData struct EventDetail: AppEntity { static var defaultQuery: EventQuery = EventQuery() var id: String var date: Date var image: Data var title: String static var typeDisplayRepresentation: TypeDisplayRepresentation = "Event" var displayRepresentation: DisplayRepresentation { DisplayRepresentation(title: "\(id) \(title)") } } struct EventQuery: EntityQuery{ func entities(for identifiers: [EventDetail.ID]) async throws -> [EventDetail] { return fill_event_details(events_list: getEventDataIntent()) } func suggestedEntities() async throws -> [EventDetail] { fill_event_details(events_list: getEventDataIntent()).filter { $0.id != "-" } } func defaultResult() async -> EventDetail? { try? await suggestedEntities().first } } struct ConfigurationAppIntent: WidgetConfigurationIntent { static var title: LocalizedStringResource = "Select an event" static var description = IntentDescription("This is an example widget.") // An example configurable parameter. @Parameter(title: "Event") var event: EventDetail // init(events: [UserCountdowns]) { // self.event = fill_event_details(events_list: events)[0] // print("AppIntent") // print(self.event.title) // } init() { } } func fill_event_details(events_list: [UserCountdowns]) -> [EventDetail] { var entities_list: [EventDetail]? let events = getEventDataIntent() for event in events { entities_list!.append(EventDetail(id: event.id!, date: event.date!, image: event.image!, title: event.title!)) } return entities_list ?? [EventDetail(id: "-", date: Date(), image: Data(), title: "empty")] } func getEventDataIntent() -> [UserCountdowns] { let context = PersistenceController.shared.container.viewContext let request = UserCountdowns.fetchRequest() var result: [UserCountdowns]! do { result = try context.fetch(request) } catch { print(error) } return result } I have been trying a few things in the widget's code but I haven't been able to make anything work, so I don't really have anything worth sharing, I think. This is the code for the UserCountdowns structure: extension UserCountdowns { @nonobjc public class func fetchRequest() -> NSFetchRequest<UserCountdowns> { return NSFetchRequest<UserCountdowns>(entityName: "UserCountdowns") } @NSManaged public var date: Date? @NSManaged public var image: Data? @NSManaged public var title: String? @NSManaged public var id: String? } Could anyone help me with this, please? What am I missing or what would the next step be? Let me know if there is any other part of the code I should share. Thank you in advance!
0
0
514
Dec ’23
Cloudkit Error: "Invalid bundle ID for container"
I get the "Permission Failure" error ("Invalid bundle ID for container") below only when running my app from my iOS Target, and not my watchkit target. The watch app is able to sync/create/delete items, but my iOS target is unable to even read the data from the cloud. The cloudkit Container ID matches my iOS Target Bundle ID, which is the apps Bundle ID. Looking at the output of CKContainer, the container matches the iOS Bundle ID. I have tried reseting multiple times, creating different cloud containers, reseting the Signing and Capabilites online. It always results in the same issue... What am I missing here? <CKError 0x281b69590: "Partial Failure" (2/1011); "Failed to modify some record zones"; uuid = D57676F8-455E-4039-9DF4-824E3BAD42BE; container ID = "iCloud.companyName.AppName"; partial errors: { com.apple.coredata.cloudkit.zone:__defaultOwner__ = <CKError 0x281b771e0: "Permission Failure" (10/2007); server message = "Invalid bundle ID for container"; op = 8CCAD43B495AADC0; uuid = D57676F8-455E-4039-9DF4-824E3BAD42BE> }>
1
0
509
Dec ’23
Connect CoreData Container to SwiftData Container
I wrote an application using SwiftData to store data. But now I have rewritten it to CoraData because I would like to expand the list of available devices for downloading. All model classes have retained their names and all parameters too, but I don’t see data from the previous version. Is it possible to get into the same container? Maybe someone can tell me the name of the default container that is created by SwiftData.
0
0
298
Dec ’23
Name clashes with SwiftData classes
I have a shopping list app and the data model is very simple, just 5 entities. These have names List, Product, Item, Section and Data. For CoreData I was able to use the auto-generated classes and gave my own names for the classes (prefixing my entity names with CD - e.g CDList) However with SwiftData I don't have that capability. My @Model classes are named List, Data etc and obviously these clash with the standard Swift/SwiftUI classes. Even the much quoted example app has the same issue a task todo list with an entity named Task, which would clash with Swift's own Task class. Is the correct/only approach that I don't use the @Model macro but roll my own SwiftData classes - e.g inline the macros, or is there a way I can give the @Model classes my own name (e.g SDList, and leave the CoreData entity names as they are). I don't really want to rename my entities if at all avoidable.
2
1
446
Dec ’23
SwiftUI not updating Core Data after change?
I've got a core data model, with a name, which I've cleverly called cdName. My view has: @Environment(\.managedObjectContext) private var viewContext @FetchRequest(sortDescriptors: [ SortDescriptor(\Item.cdName), ]) private var items: FetchedResults<Item> and then, later ForEach(self.items, id: \.self) { item in NavigationLink { ItemView(item: item) .environment(\.managedObjectContext, self.viewContext) } label: { LabelWithMenuView(label: item.cdName ?? "<no name>") { ptr in if let newName = ptr { let oldName = item.cdName! item.cdName = newName do { try self.viewContext.save() } catch { print("Could not save rename of \(oldName) to \(newName)") } } (LabelWithMenuView is a view that has an on-hover button which brings up a rename sheet and passes the new name off to the completion handler.) When I do this (macOS)... it does change the name in Core Data, but it doesn't update the view. If I quit&restart my app, it shows up with the new name. What am I doing wrong, please?
3
0
549
Nov ’23
How to use finishDeferredLightweightMigrationTask
The documentation states that you can use either finishDeferredLightweightMigrationTask or finishDeferredLightweightMigration to complete a deferred migration at a later time. However when I tried finishDeferredLightweightMigrationTask, I noticed that the metadata for the store isn't updated. How would you know when the migration has completed and you can stop calling finishDeferredLightweightMigrationTask? The reason I was reaching for the individual migration task approach is that I thought it would be better for handling an expired background task since I could check for cancellation after each step.
0
0
256
Nov ’23
How to safely access Core data NSManagedObject attributes from a SwiftUI view using swift concurrency model?
How do I safely access Core data NSManagedObject attributes from SwiftUI view using the swift concurrency model. My understanding is we need to enclose any access to NSManageObject attributes in await context.perform {}. But if I use it anywhere in a view be that in the body(), or init() or .task() modifier I get the following warnings or errors: for .task{} modifier or if within any Task {}: Passing argument of non-sendable type 'NSManagedObjectContext.ScheduledTaskType' outside of main actor-isolated context may introduce data races this happens even if I create a new context solely for this access. if within body() or init(): 'await' in a function that does not support concurrency but we cant set body or init() to async an example of the code is something along the lines of: var attributeString: String = "" let context = PersistentStore.shared.persistentContainer.newBackgroundContext() await context.perform { attributeString = nsmanagedObject.attribute! }
2
1
890
Dec ’23
closure #1 in closure #1 in CoreDataManager.persistentContainer.getter
Hello everyone, I am experiencing a very weird issue. There are two scenario, and the crash issue direct to persistentContainer.getter last. I know the error is occur in this line : CoreDataManager.persistentContainer.getter + 51 code block: fatalError("Unresolved error \(error), \(error.userInfo)") scenario1, Xcode crash report: scenario 2, firebase crashlystic: detail info: ProjectName/CoreDataManager.swift:51: Fatal error: Unresolved error Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={sourceURL=file:///private/var/mobile/Containers/Shared/AppGroup/8DA377D9-5CE2-47BB-A985-8A8B7CCD071C/FraudInfo.sqlite, reason=Cannot migrate store in-place: I/O error for database at /private/var/mobile/Containers/Shared/AppGroup/8DA377D9-5CE2-47BB-A985-8A8B7CCD071C/FrankInfo.sqlite. SQLite error code:1, 'duplicate column name: ZISSEARCH', destinationURL=file:///private/var/mobile/Containers/Shared/AppGroup/8DA377D9-5CE2-47BB-A985-8A8B7CCD071C/FrankInfo.sqlite, NSUnderlyingError=0x283398de0 {Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={NSSQLiteErrorDomain=1, NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/8DA377D9-5CE2-47BB-A985-8A8B7CCD071C/FrankInfo.sqlite, NSUnderlyingException=I/O error for database at /private/var/mobile/Containers/Shared/AppGroup/8DA377D9 The “duplicate column name: ZISSEARCH'” issue, we had been update xcdatamodel version, Old version user was update to newest app version, but migration fail, why the crash occurring the newest version? But I can’t reproduce the crash, and I have no idea how to fix this. please support me how can I handle the issue, thanks more.
0
0
440
Nov ’23
MacOS App Core Data app is stuck in "This NSPersistentStoreCoordinator has no persistent stores (schema mismatch or migration failure). It cannot perform a save operation."
I work on a MacOS app (which has a companion iOS app) that uses Core Data with NSPersistentCloudKitContainer. The app also supports widgets and hence there is a need to migrate the persistent store within the core data stack using replacePersistentStore( at:.... During development I recently created a new model version and added a new entity, replaced some attributes etc... Working on the iOS app is fine because deleting the app clears all the data allowing me to work with a clean slate. On MacOS, I initially thought that I could simply navigate to the app group file location, delete the .sqlite file, along with the sqlite-shm and sqlite-wal. I also went and deleted the CloudKit related files. I did all of this out of pure ignorance - my expectation was that it would give me a clean slate, but it did not. This instead gave me some unpredictable behaviour, but the app was always in a bad state. the issues I saw were; • migration failure, • sqlite errors highlighting no such column: t0 - where all the new entity details were missing in sqlite completely After finding a post in the forums about how to reset macOS correctly, I did this instead - do { try container.persistentStoreCoordinator.destroyPersistentStore(at: container.persistentStoreDescriptions.first!.url!, type: .sqlite, options: nil) try container.persistentStoreCoordinator.destroyPersistentStore(at: storeURL, type: .sqlite, options: nil) } catch { print(String(describing: error)) } And now I am back to the ongoing error of This NSPersistentStoreCoordinator has no persistent stores (schema mismatch or migration failure). It cannot perform a save operation. Another thing to note - whenever running the destroyPersistentStore( I have tried this on both the URLs of the old store location and the new one (in the app group). This still doesn't seem to help. AND I noticed that while destroyPersistentStore does get rid of the .sqlite file, it does not delete the sqlite-shm and sqlite-wal - could this be the problem? and do I need to delete these manually? public class CoreDataManager { public static let shared = CoreDataManager() private enum Constants { #if os(macOS) static let appGroupName = "2MM2V2959F.wabitime.group" #elseif os(iOS) static let appGroupName = "group.wabitime" #endif static let containerName = "WabiTimeDataModel" /// The name of the sql database file static let databaseName = "wabitime_database" /// The identifier for the container static let containerIdentifier = "iCloud.com.jslomowitz.WabiTime" } public lazy var context = persistentContainer.viewContext lazy var managedObjectModel: NSManagedObjectModel = { guard let wabiDataBundle = Bundle.module.url( forResource: Constants.containerName, withExtension: "momd" ), let managedObjectModel = NSManagedObjectModel(contentsOf: wabiDataBundle) else { assertionFailure("cannot find managedObjectModel") return NSManagedObjectModel() } return managedObjectModel }() lazy var persistentContainer: NSPersistentCloudKitContainer = { let container = NSPersistentCloudKitContainer( name: Constants.containerName, managedObjectModel: managedObjectModel ) /// URL of the old sql database that has not been relocated to the app group var oldStoreURL: URL? { guard let storeDescription = container.persistentStoreDescriptions.first, let url = storeDescription.url, FileManager.default.fileExists(atPath: url.path) else { return nil } return url } /// URL of the sql database in the app group var storeURL: URL { guard let fileContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: Constants.appGroupName) else { fatalError("Shared file container could not be created") } return fileContainer.appendingPathComponent("\(Constants.databaseName).sqlite") } // assign the shared container if the old store has been deleted if oldStoreURL == nil { let description = NSPersistentStoreDescription(url: storeURL) description.shouldInferMappingModelAutomatically = true description.shouldMigrateStoreAutomatically = true container.persistentStoreDescriptions = [description] } // perform store migration if necessary if let url = oldStoreURL, url.absoluteString != storeURL.absoluteString { let coordinator = container.persistentStoreCoordinator do { let storeOptions = [ NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true ] try coordinator.replacePersistentStore( at: url, withPersistentStoreFrom: storeURL, sourceOptions: storeOptions, type: .sqlite ) } catch { print(error.localizedDescription) } self.deleteOldStore(with: url) } let options = NSPersistentCloudKitContainerOptions(containerIdentifier: Constants.containerIdentifier) guard let description = container.persistentStoreDescriptions.first else { fatalError("Could not retrieve a persistent store description.") } description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) description.cloudKitContainerOptions = options container.loadPersistentStores(completionHandler: { [weak self] (_, error) in guard let self, error == nil else { assertionFailure("Unresolved error: \(String(describing: error))") return } }) container.viewContext.automaticallyMergesChangesFromParent = true container.viewContext.mergePolicy = NSMergePolicy(merge: .mergeByPropertyObjectTrumpMergePolicyType) return container }() private func deleteOldStore(with url: URL) { let fileCoordinator = NSFileCoordinator() fileCoordinator.coordinate(writingItemAt: url, options: .forDeleting, error: nil) { url in do { try FileManager.default.removeItem(at: url) } catch { print(error.localizedDescription) } } } // MARK: - Core Data Saving and Undo support func saveContext(completion: (() -> Void)? = nil) { #if os(macOS) if !context.commitEditing() { NSLog("AppDelegate unable to commit editing before saving") } #endif if context.hasChanges { do { try context.save() print("SAVED") completion?() } catch { let nserror = error as NSError #if os(macOS) NSApplication.shared.presentError(nserror) #endif } } } }
2
1
493
Nov ’23
SwiftData - different containers in one app
Hello to team, I have a very challenging issue that I'm not able to fix. I have an app that works with SwiftData Model Container that is generated when the app is launched. In the app I also added a Demo Mode area, where the user can load a mock data and simulating app behavior with more data. In order to switch to demo mode, I'm loading new UI layer and loading a new model container, which is configured to work with the same scheme, but isStoredInMemoryOnly = true. Everything works fine. Now, when the user toggles off the demo mode and go back to the main UI, any persistent changes to the modelContext leads to a crash where it says that the create store is different from the open store. Tried almost everything - I'm not sure even if it's possible to have this flow with SwiftData, butI'm trying. Please advice. Thanks a lot!
0
1
558
Nov ’23
Core Data error: 'cannot use an attribute type of "Composite"' when "Used with CloudKit" checked
Hello, I'm running into an odd error. I'm trying to add a composite attribute called period to a Core Data Entity named Report, but I'm getting a compile-time error that points to my xcdatamodel file: Report.period cannot use an attribute type of "Composite". In my model configuration I have "Used with CloudKit" box checked. If I uncheck this box, the error goes away and everything builds fine. But the documentation for NSCompositeAttributeDescription says: You may use composite attributes anywhere you use standard attributes, including lightweight migrations and CloudKit, through NSPersistentCloudKitContainer. So it seems like I should be able to use composite attributes in Core Data with CloudKit syncing enabled. What am I missing here? Is this a bug, or am I doing something wrong?
2
0
316
Oct ’23
Xcode 15: Core Data : No NSValueTransformer with class name *** was found for attribute YYY on entity ZZZ for custom `NSSecureUnarchiveFromDataTransformer`
Hi, I am creating a custom NSSecureUnarchiveFromDataTransformer in order to handle attributes of entities of type NSDateComponents. It all works and I did not see any warnings in the "Issue navigator" inside Xcode but with Xcode 15 I started seeing this warning: /Users/.../CustomNSSecureUnarchiveFromDataTransformer/CoreData:1:1 no NSValueTransformer with class name 'CustomSecureUnarchiveFromDataTransformer' was found for attribute 'testDate' on entity 'Item' My use case is very simple, I have this custom transformer: @objc(CustomSecureUnarchiveFromDataTransformer) final class CustomSecureUnarchiveFromDataTransformer: NSSecureUnarchiveFromDataTransformer { override class var allowedTopLevelClasses: [AnyClass] { return [NSDateComponents.self] } static let name = NSValueTransformerName(rawValue: String(describing: CustomSecureUnarchiveFromDataTransformer.self)) public static func register() { let transformer = CustomSecureUnarchiveFromDataTransformer() ValueTransformer.setValueTransformer(transformer, forName: name) } } which is set to the Core data entity's "Transformer": which leads to the warning in Xcode 15. App works just fine and there are no problems during run time, but this warning is shown and I want to fix it. Here is a simple test project https://github.com/VladimirAmiorkov/CustomNSSecureUnarchiveFromDataTransformer
10
9
2.2k
2w
new swift concurrency model with core data willSave()
anyone know how to use the new swift concurrency model (ie. await context.perform and context.perform) core data willSave()? for example. how would I ensure this is thread safe? changing self.managedObjectContext!.performAndWait to await self.managedObjectContext!.perform means I have to change willSave() to async which then means it never gets called because its not overriding the correct method anymore. override public func willSave() { self.managedObjectContext!.performAndWait { if self.modifiedDate == nil || Date().timeIntervalSince(self.modifiedDate!) >= 1 { self.modifiedDate = Date() } } super.willSave() }
0
0
543
Oct ’23