From core data I generate data for map marker pins. When user selects a marker pin I display the data in a popup label with multiple rows, when I click on the pin. This is working for one marker pin. Now, I need to iterate over a list and generate several of those markers each with unique popup label data.
The code:
struct MapView: UIViewRepresentable {
var annotationOnTap: (_ title: String) -> Void
@Binding var pins: [GpsData.MyEndPt]
let key: String
private static var mapViewStore = [String : MKMapView]()
func makeUIView(context: Context) -> MKMapView {
if let mapView = MapView.mapViewStore[key] {
mapView.delegate = context.coordinator
return mapView
}
let mapView = MKMapView(frame: .zero)
mapView.delegate = context.coordinator
MapView.mapViewStore[key] = mapView
return mapView
}
func updateUIView(_ uiView: MKMapView, context: Context) {
uiView.addAnnotations(pins)
}
func makeCoordinator() -> MapCoordinator {
MapCoordinator(self)
}
final class MapCoordinator: NSObject, MKMapViewDelegate {
var parent: MapView
init(_ parent: MapView) {
self.parent = parent
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let PINID:String = "MyEndPoint"
var mPin: MKMarkerAnnotationView? = nil
let subtitleView = UILabel()
subtitleView.font = subtitleView.font.withSize(12)
subtitleView.numberOfLines = 0
if (mPin == nil ) {
mPin = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: PINID)
mPin?.canShowCallout = true
} else{
mPin?.annotation = annotation
}
mPin?.leftCalloutAccessoryView = nil
let btn = UIButton(type: .detailDisclosure)
mPin?.rightCalloutAccessoryView = btn
let zip:String = "77065"
let formattedSalesStr:String = "100"
let totalTargetText:String = "500"
let paddedLoad = formattedSalesStr.padding(toLength: 50, withPad: " ", startingAt: 0)
let paddedCapacity = totalTargetText.padding(toLength: 50, withPad: " ", startingAt: 0)
subtitleView.text = "Total sales: "
subtitleView.text! += paddedLoad
subtitleView.text! += " \r\n"
subtitleView.text! += "Total Target: "
subtitleView.text! += paddedCapacity
subtitleView.text! += " \r\n"
subtitleView.text! += paddedzip
mPin!.detailCalloutAccessoryView = subtitleView
return mPin!
}
}
}
As you can see in the above method I have hardcoded values for my popup marker label. So I tried to iterate over the @Binding pins, populate each mPin, and return an array of MKAnnotationView, like this:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> [MKAnnotationView] {
let PINID:String = "MyEndPoint"
var i:Int = 1
var mPins = [MKAnnotationView]()
for detail in self.parent.pins {
var mPin: MKMarkerAnnotationView? = nil
let subtitleView = UILabel()
subtitleView.font = subtitleView.font.withSize(12)
subtitleView.numberOfLines = 0
if (mPin == nil ) {
mPin = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: PINID)
mPin?.canShowCallout = true
} else{
mPin?.annotation = annotation
}
mPin?.leftCalloutAccessoryView = nil
let btn = UIButton(type: .detailDisclosure)
mPin?.rightCalloutAccessoryView = btn
subtitleView.text! += String(i)
subtitleView.text = "Total Load: "
subtitleView.text! += String(detail.sales)
subtitleView.text! += " \r\n"
subtitleView.text! += "Total Target: "
subtitleView.text! += String(detail.target)
subtitleView.text! += " \r\n"
i += 1
// }
mPin!.detailCalloutAccessoryView = subtitleView
mPins.append(mPin!)
}
return mPins
}
The marker pins show up, but then the label does not popup. How to fix this?
Core Data
RSS for tagSave 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
Hi all
In pursuit of adopting widgets in my application, I have transitioned from AppSupport to AppGroup as storage location for Core Data. I have done a migration process/flow that goes as follows and which have been tested multiple times although I have yet to publish the update:
Check if migration has taken place or not
1a. if yes continue to app
1b. If no continue flow
Begin migration process
2a. Backup original store in AppSupport
2b. Migrate store to AppGroup
2c. Migrate userdefaults to AppGroup
2d. Update userdefaults with true for both hasMigratedToAppGroup and hasMigratedUserDefaultsToAppGroup
Is there any tips or stuff to look for that hasn’t been taken in to account? How have you done it previously, and what would be recommended? Also, is there some specific tests to run/over many times get a baseline of how many is succeeding or failing?
Thanks in advance.
Suggestions on what is causing this? Where to look? Could it be related to having a CoreData 'abstract entity' that occurs in two configurations - one configuration for 'public' and one for 'private/shared'?
I'm currently facing an interesting issue. A customer is reporting back that my app is crashing on launch for them. I can see the crash logs (using AppCenter for crash management), and the reason the app is crashing seems to be in CoreData:
(Attaching text for seachability, and screenshot for readability):
libsystem_platform.dylib
_platform_memmove$VARIANT$Haswell
CoreData
-[_PFExternalReferenceData initForExternalLocation:safeguardLocation:data:protectionLevel:]
CoreData
-[NSSQLSavePlan _populateRow:fromObject:timestamp:inserted:shouldAddToRowCache:]
CoreData
-[NSSQLSavePlan _createRowsForSave]
CoreData
-[NSSQLSaveChangesRequestContext executePrologue]
CoreData
-[NSSQLCore dispatchRequest:withRetries:]
CoreData
-[NSSQLCore executeRequest:withContext:error:]
CoreData
-[NSPersistentStoreCoordinator executeRequest:withContext:error:]
CoreData
-[NSPersistentStoreCoordinator _routeHeavyweightBlock:]
CoreData
-[NSPersistentStoreCoordinator executeRequest:withContext:error:]
CoreData
-[NSManagedObjectContext save:]
I have never seen that crash before, it's the first time it is appearing since CoreData has been incorporated into the app (in 2016 or so). Any hints on what could possibly be happening? I am unable to provoke the crash on my end, thus debugging is quite interesting.
When I add or delete data of my entity type I can see the updates (between the simulator and the phone) but when i edit I dont see the updates although table view is reloaded. The console says
Ignoring remote change notification because it didn't change any entities tracked by persistent history
When I rebuild the app for both device and simulator I see it reflecting the most current changes.
Any help?
Neerav
Hello, developers,
I'm experiencing UI lag in SwiftUI when updating Core Data or SwiftData entities in the background, noticeable during scrolling. This issue arises regardless of whether the updated entity is currently displayed. For instance, updating a "Song" entity with a new localURL from a background download and saving background context affects an unrelated "Artists" list view.
Scenario: The lag is most evident when completing background downloads and updating entity properties, causing a hitch in scrolling interactions when using SwiftUI @FetchRequest or @Query for displaying data.
Observations:
The issue occurs with both Core Data @FetchRequest and SwiftData @Query property wrappers.
It affects unrelated views, suggesting a broader issue with SwiftUI's handling of data updates during user interactions.
Seeking Community Insights:
Has anyone faced similar issues with SwiftUI and background data updates?
Any strategies for reducing this lag/hitch?
Insights into SwiftUI's data update and view re-rendering process in this context?
For a practical example, Apple's project on loading and displaying a large data feed demonstrates this issue. Try tapping the refresh button while scrolling to observe the lag.
Appreciate any advice or solutions!
Best Regards,
[Personal Information Edited by Moderator]
Can anyone tell me how to use Swift Data and Core Data with playground?
I have a CoreData entity with a transformable property data that stores an NSDictionary. All of the classes inside the dictionary conform to NSSecureCoding
I have been getting many instances of this warning :
'NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release
In trying to clean up the warning and future-proof my app, but I am running into a lot of trouble.
My understanding is that using NSKeyedUnarchiveFromData as the transformer in my data properties attribute should work, since the top level class is a dictionary and all of the contents conform to NSSecureCoding.
However, my data dictionary is now coming back as NSConcreteMutableData so I cannot access the data in it.
I have also tried creating a custom value transformer with additional allowedTopLevelClasses, but that hasn't helped, and again, the topLevel type is an NSDictionary, which should be allowed.
Thank you for any guidance.
I'm experiencing an unresponsive UI since MacOS 14.0 and iOS 17.0 when calling record(for: ) or recordID(for:) on the instance of NSPersistentCloudKitContainer.
On MacOS, the UI freeze almost always happens when calling the function.
On iOS, it is necessary that the device (or simulator) does not have any network connection.
I would like to ask if anyone experienced the same problem. I have posted the problem twice to Apple via the Feedback app (once for iOS and once for MacOS). No reply yet on MacOS but on iOS Apple marked it as resolved because apparently no one but me has experienced this problem.
In the meantime, I have set up a minimum reproducible example app (MRE).:
https://github.com/DominikButz/NotesApp-Cloud-Kit-Record-UI-Freeze-
Anyone interested, please read the readme of the repository. It includes step by step instructions on how to reproduce the bug.
I can't rule out I have misunderstood the usage of CoreData and CloudKit - in that case please point me in the right direction.
The app I'm working on should also work offline (and on MacOS!) but it doesn't do so properly as long as this bug exists.
I'm exploring switching to SwiftData (which would mean no one using macOS 13 / iOS 16 can use my app...) but I would still need to access cloud kit records even with SwiftData and I fear the bug also exists in SwiftData.
Thanks
In Core data public configuration, added new attribute to entities, new entities, but the changes are neither synchronized nor data is transferred to existing container schema in cloudkit.
private var _publicPersistentStore: NSPersistentStore?
var publicPersistentStore: NSPersistentStore {
return _publicPersistentStore!
}
private var _privatePersistentStore: NSPersistentStore?
var privatePersistentStore: NSPersistentStore {
return _privatePersistentStore!
}
private var _sharedPersistentStore: NSPersistentStore?
var sharedPersistentStore: NSPersistentStore {
return _sharedPersistentStore!
}
static let shared = PersistenceController()
static var preview: PersistenceController = {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
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: “GS”)
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
guard let defaultDescription = container.persistentStoreDescriptions.first else {
fatalError("###\(#function): failed to retrieve a persistent store description.")
}
let containerIdentifier = defaultDescription.cloudKitContainerOptions!.containerIdentifier
print(containerIdentifier)
print(defaultDescription.url as Any)
let url = defaultDescription.url?.deletingLastPathComponent()
print(url as Any)
// Public
let publicDescription = NSPersistentStoreDescription(url: url!.appendingPathComponent("public.sqlite"))
publicDescription.configuration = "Public"
print(publicDescription.url)
let publicOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: containerIdentifier)
publicOptions.databaseScope = .public
publicDescription.cloudKitContainerOptions = publicOptions
publicDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
publicDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
// Private
let privateDescription = NSPersistentStoreDescription(url: url!.appendingPathComponent("private.sqlite"))
privateDescription.configuration = "Private"
print(privateDescription.url)
let privateOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: containerIdentifier)
privateOptions.databaseScope = .private
privateDescription.cloudKitContainerOptions = privateOptions
privateDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
privateDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
// Shared
guard let sharedDescription = privateDescription.copy() as? NSPersistentStoreDescription else {
fatalError("#\(#function): Copying the private store description returned an unexpected value.")
}
sharedDescription.url = url!.appendingPathComponent("shared.sqlite")
print(sharedDescription.url)
sharedDescription.configuration = "Shared"
let sharedOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: containerIdentifier)
sharedOptions.databaseScope = .shared
sharedDescription.cloudKitContainerOptions = sharedOptions
sharedDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
sharedDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.persistentStoreDescriptions = [publicDescription, privateDescription, sharedDescription]
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.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
else {
if let cloudKitContainerOptions = storeDescription.cloudKitContainerOptions {
if #available(iOS 16.0, *) {
if .public == storeDescription.cloudKitContainerOptions?.databaseScope {
print("loaded public store")
// self._publicPersistentStore = container.persistentStoreCoordinator.persistentStore(for: storeDescription.url!)
} else if .private == storeDescription.cloudKitContainerOptions?.databaseScope {
print("loaded private store")
//self._privatePersistentStore = container.persistentStoreCoordinator.persistentStore(for: storeDescription.url!)
} else if .shared == storeDescription.cloudKitContainerOptions?.databaseScope {
print("loaded shared store")
//self._sharedPersistentStore = container.persistentStoreCoordinator.persistentStore(for: storeDescription.url!)
}
} else {
// Fallback on earlier versions
}
}
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy // external changes trumping in-memory changes.
}
func save() {
let context = container.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Show some error here
print("save error")
}
}
}
}
Tried new container on cloudkit, problem persists. Working previously until I updated Xcode to 15.2 and iOs 16.2. Can you please tell me why coredata is not synchronized for public configuration.
We are facing a challenging memory issue during a Core Data heavy weight migration in our app.
Background: We store sizable data(~250kb/record) in a Core Data entity called "Email." We have roughly 20k records. We are loading the "Email" list using fetchedResultsController with batching. Recently, we split the another entity named "Profile" into "Profile" and "Address" entities, requiring a heavyweight migration.
The Problem: This migration consumes an exorbitant amount of memory, causing the OS to kill our app. Interestingly, the "Email" entity is causing the brunt of the memory usage, even though the actual migration code deals with the "Profile" entity to create "Address." If we remove the "sizable" data from "Email" and attempt for migration then the migration is successful.
My Questions: Is this memory consumption expected behavior? Why does the "Email" entity, seemingly unrelated to the actual migration, seem to be the main memory culprit?
How can I prevent the OS from terminating my app during migration? Are there strategies to optimize memory usage or mitigate memory pressure?
Also we are encountering a delay in loading the email list on the very first launch of app. Subsequent launches work comparatively faster. Is that related to storing bigger size data in Email entity?
We have an entity called "EMail" with attributes such as ID, From, To, Subject, Body.
Due to various reasons including performance for retrieval, impact on migration etc, we want to refactor this entity into two entities with a parent child relationship: "EMail": ID, From, To, Subject and "EMailBody": ID, Body.
Can this be done with an existing model? If so, will this still fall under lightweight migration?
I'm trying to add two more data models SectionsSD andArticles SD to an existing project using SwiftData where I had one model and am running into a variety of CoreData errors when I try to run my app. I am running Xcode 15.2 and the latest iOS simulator at iOS 17.2
Here is my container
let container: ModelContainer = {
let schema = Schema([
LocationData.self,
SectionsSD.self,
ArticlesSD.self
])
let container = try! ModelContainer(for: schema, configurations: [])
return container
}()
After I add these two models I get the following errors and I can't load data into the SectionsSD and ArticlesSD models. If I comment out my LocataionData model that works w/o error or if I run just LocationData it runs without error but run all together and I get the following errors in the log:
error: Error: Persistent History (11) has to be truncated due to the following entities being removed: (
SectionsSD,
ArticlesSD
)
CoreData: error: Error: Persistent History (11) has to be truncated due to the following entities being removed: (
SectionsSD,
ArticlesSD
)
warning: Warning: Dropping Indexes for Persistent History
CoreData: warning: Warning: Dropping Indexes for Persistent History
warning: Warning: Dropping Transactions prior to 11 for Persistent History
CoreData: warning: Warning: Dropping Transactions prior to 11 for Persistent History
warning: Warning: Dropping Changes prior to TransactionID 11 for Persistent History
Any advice here would be appreciated. These are initial models so migration is not really a need yet. Seems to just **** if you add more models.
As the title says, our app has begun running into a strange issue every time a user upgrades their iPhone to the latest iOS versions. It started in 17.2.1 and looks like it made a resurgence in 17.3. Post update the user's FullText Searches against the local sqlite db run egregiously slow. Fully re-installing the app and re-downloading all content seems to correct the issue, after which their searches come back in less than 500 ms tops. When the bug occurs searches can take upwards of 15 secs in some cases to complete... What makes no sense is why all of a sudden this is happening in 17.2.1 >=
Our app uses an old school approach (historic code we never removed) to create a local sqlite database from scratch on first app install in the user's device contentDir. this .db file is instantiated on each app load using the following:
private func sqliteOpenDB(url: URL) -> OpaquePointer? {
var db: OpaquePointer?
if sqlite3_open_v2(url.path, &db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX, nil) == SQLITE_OK {
LoggingUtil.log(msg: "\(ContentFilestore.TAG): database file opened successfully")
// You must enable foreign key constraints every time the db connects otherwise they're off by default and cascade deletes/fk's won't work
sqlite3_exec(db, "PRAGMA foreign_keys = ON;", nil, nil, nil)
} else {
LoggingUtil.log(msg: "\(ContentFilestore.TAG) Error: unabled to open the database file")
}
return db;
}
Prior to iOA 17.2.1 we've never had an issue with this when a user's device upgraded the OS. Now this process continues to work without throwing an error or warning of any kind, but their FTS search db slows to a crawl. It also seems to be completely isolated to the FTS virtual table as well. The actual tables run just fine.
My question is did something major change in iOS 17.2.1 >= that I'm missing that would be causing virtual tables to lose their indexing or have some kind of issue that would cause this problem?
Is there a way to share CoreData data containing complex relationships easily by file? And also to create them easily after receiving the file?
The application runs on a secure iPad without iCloud, so CloudKit is not an option.
I'd really like to keep the file principle, so that data can be shared via Airdrop, e-mail, file transfer, etc.
The ideal would be :
data = myNSManagedObject.toJSON()
file = createFile(data)
share file
receive file
data = file.data.decodeJSON()
myNSManagedObjectContext.add(data)
All this without having to browse all the objects to create them individually
Thx
In our app, there is a scenario where we write and delete approximately 100MB of files to the iCloud server at once using NSPersistentCloudkItContainer(CoreData). While write, read, and delete operations are immediately reflected in the local database, there is a noticeable delay when accessing the CloudKit Database dashboard.
Here is the testing approach we have tried:
Data Insert Test
Prepare around 100MB of data.
Write the data to CoreData on device A.
When launching the app on device B, it takes about 5 minutes for the data to be fully synchronized.
Data Deletion Test
Remove all the added data on device A (immediately reflected in local storage.)
After performing step 1, leaving device A idle takes about 3 minutes for the deletion to be reflected on device B.
if the app is deleted on device A after step 1, deletion information does not reach device B. Upon reinstalling the app on device A, the deleted data reappears on device B (synchronized data).
The ongoing occurrence of these issues has raised several questions regarding cloud synchronization and synchronization speed:
Is the synchronization speed of the Testflight app the same as the one received from the AppStore?
Are there traffic limitations per account or device?
Despite different perceived speeds for each account or device, is there any factor influencing synchronization speed other than network conditions?
Hi all,
I have an iOS app which uses CloudKit and the standard NSPersistentCloudKitContainer, which I rely on for syncing app data between the user's devices. If the user's iCloud account is full I can see a log message while debugging in Xcode shortly after startup which looks something like this:
error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _requestAbortedNotInitialized:](2183): <NSCloudKitMirroringDelegate: 0x281ddc1e0> - Never successfully initialized and cannot execute request '<NSCloudKitMirroringExportRequest: 0x2841e00f0> 51383346-87BA-44D8-B527-A0B1EE35A0EF' due to error: <CKError 0x282c50db0: "Partial Failure" (2/1011); "Failed to modify some records"; uuid = 7BA17495-4F05-4AF4-A463-C0DF5A823B2E; container ID = "iCloud.com.neufsters.pangram"; partial errors: {
E30B2972-FD4B-4D2A-BD1C-EB6F33F5367D:(com.apple.coredata.cloudkit.zone:__defaultOwner__) = <CKError 0x282c155f0: "Quota Exceeded" (25/2035); server message = "Quota exceeded"; op = FC4D3188D0A46ABC; uuid = 7BA17495-4F05-4AF4-A463-C0DF5A823B2E; Retry after 315.0 seconds>
2FC9A487-D630-444D-B7F4-27A0F3A6B46E:(com.apple.coredata.cloudkit.zone:__defaultOwner__) = <CKError 0x282c52820: "Quota Exceeded" (25/2035); server message = "Quota exceeded"; op = FC4D3188D0A46ABC; uuid = 7BA17495-4F05-4AF4-A463-C0DF5A823B2E; Retry after 315.0 seconds>
903DD6A0-0BD8-46C0-84FB-E89797514D9F:(com.apple.coredata.cloudkit.zone:__defaultOwner__) = <CKError 0x282c513e0: "Quota Exceeded" (25/2035); server message = "Quota exceeded"; op = FC4D3188D0A46ABC; uuid = 7BA17495-4F05-4AF4-A463-C0DF5A823B2E; Retry after 315.0 seconds>
}>
I would like to know how I can get a callback of some sort so I can run code if this CloudKit/CoreData error happens. In particular I'd like to put up some sort of warning to the user letting them know their data isn't going to sync.
Please note that I'm not looking for how to do error handling as a result of a user-initiated CloudKit API call. I'm looking for how to get notified when the background syncing logs errors like the above.
Thanks,
Russ
I'm trying to setup a filter option for some core data records, but I'm not seeing the expected results.
Essentially, what I want is to have multiple sections. Within each section it would be an OR query, and an AND between each section. I've tried setting it up as below.
func getBasicFilter() -> NSPredicate? {
var predicatesBagsLeft : [NSPredicate] = []
var predicatesDrillType : [NSPredicate] = []
var andPredicates : [NSPredicate] = []
print("Filter List")
print(filters)
// Bags Left
if let show = filters["showFullLeft"] {
if show {
print("Predicates : Show Full")
let predicate = NSPredicate(format: "ANY projectColours.fullLeft > 0")
predicatesBagsLeft.append(predicate)
}
}
if let show = filters["showPartialLeft"] {
if show {
print("Predicates : Show Partial")
let predicate = NSPredicate(format: "ANY projectColours.partialLeft > 0")
predicatesBagsLeft.append(predicate)
}
}
// Drill Types
if let show = filters["showSquareOnly"] {
if show {
print("Predicates : Show Square Only")
let predicate = NSPredicate(format: "ANY projectColours.project.drillType = %@", "Square")
predicatesDrillType.append(predicate)
}
}
// Drill Manufacturers - TO DO
// Combine Predicates
if predicatesBagsLeft.count > 0 {
let predicatesForBagsLeft = NSCompoundPredicate(type: .or, subpredicates: predicatesBagsLeft)
andPredicates.append(predicatesForBagsLeft)
}
if predicatesDrillType.count > 0 {
let predicatesForDrillType = NSCompoundPredicate(type: .or, subpredicates: predicatesDrillType)
andPredicates.append(predicatesForDrillType)
}
if andPredicates.count > 0 {
let predicates = NSCompoundPredicate(type: .and, subpredicates: andPredicates)
return predicates
}
return nil
}
It does filter, but doesn't seem to be applying both correctly. I'm testing with a filter of showFullLeft & showSquareOnly, so it should show only squares which have a a fullest > 0
I'm getting 7 results back, but one of them is unwanted. It is square, but it has 0 for both full & partial
When I look at the query core data is using it looks correct
CoreData: sql: SELECT t0.ZMANU, COUNT (DISTINCT t0.Z_PK) FROM ZCOLOUR t0 JOIN ZPROJECTCOLOUR t1 ON t0.Z_PK = t1.ZCOLOUR JOIN ZPROJECTCOLOUR t2 ON t0.Z_PK = t2.ZCOLOUR JOIN ZPROJECT t3 ON t2.ZPROJECT = t3.Z_PK WHERE ( t1.ZFULLLEFT > ? AND t3.ZDRILLTYPE = ?) GROUP BY t0.ZMANU ORDER BY t0.ZMANU
CoreData: details: SQLite bind[0] = 0
CoreData: details: SQLite bind[1] = "Square"
It is often the case that offline devices can add duplicate entities that needs to be merged when CloudKit syncs. Consider user-created tags. A user might create a Note, and then tag it with a newly created tag “Family.” On a separate offline device, they might create another note, and create another tag also called ”Family.” On device sync, both duplicate ”Family” tags would need to be identified as duplicates based on their name property, merged to a single entity, and their original relationships consolidated to the single merged Tag. And this needs to happen before the CloudKit sync data is presented to the UI in the main context.
With Core Data we have the mechanism to consume relevant store changes described here.
These tools allow us to listen for remote change, then process them appropriately (e.g. remove / merge duplicates) and then merge the changes into the app’s main context. This perfectly solves the problem described in the first paragraph above. Apple provides code using this mechanism for deduplicating tags in a sample app.
Is there a mechanism to solve this deduplication problem using SwiftData technology without implementing and maintaining a parallel Core Data stack?
What is the recommended architecture for a CoreData+CloudKit iOS App that has a large public database?
Assume the public database contains 10,000+ Locations from which a User would select a few as favorites. Totally impractical to mirror the locations such that they appear in the App's CoreData having been synced from the .public CloudKit database. Presumably one uses the CloudKit API to query the .public database and display some subset of locations for the User to select? (The selected locations can then be stored in the Users .private (or perhaps .shared) database.)
How does one configure CoreData + CloudKit for this scenario? Is there another approach?