I just want to share that I have a Core Data app with the following:
Each of them is a button where user can press to filter out the data for example (left to right): All, Inbox, Archive, More, Good, Evil, Important. You will also note that each of this button has a counter.
In my ViewModel, I have a function to count each of them, which is called when in the app's onAppear()
func countItem() -> (countTotal: Int, countArchive: Int, countGood: Int, countEvil: Int, countImportant: Int) {
let request: NSFetchRequest<ThoughtEntity> = ThoughtEntity.fetchRequest()
request.predicate = NSPredicate(format: "thoughts != %@", "")
let items1 = (try? manager.container.viewContext.fetch(request)) ?? []
let countTotalPredicate = items1.count
request.predicate = NSPredicate(format: "isArchive == true")
let items2 = (try? manager.container.viewContext.fetch(request)) ?? []
let countArchivePredicate = items2.count
request.predicate = NSPredicate(format: "type CONTAINS %@", "good")
let items3 = (try? manager.container.viewContext.fetch(request)) ?? []
let countGoodPredicate = items3.count
request.predicate = NSPredicate(format: "type CONTAINS %@", "evil")
let items4 = (try? manager.container.viewContext.fetch(request)) ?? []
let countEvilPredicate = items4.count
request.predicate = NSPredicate(format: "type CONTAINS %@", "important")
let items5 = (try? manager.container.viewContext.fetch(request)) ?? []
let countImportantPredicate = items5.count
return (countTotalPredicate, countArchivePredicate, countGoodPredicate, countEvilPredicate, countImportantPredicate)
}
The code works well enough.
I am wondering is there a better way to do it instead of fetching it from the database 5 times? Perhaps the "cost" of fetching is low, so it doesn't matter but I am wondering if there is a better, more efficient way of doing it?
You can use the count(for:)
method on the viewContext to return just the count, not all of the entities.
let request: NSFetchRequest<ThoughtEntity> = ThoughtEntity.fetchRequest()
request.predicate = NSPredicate(format: "thoughts != %@", "")
let countTotalPredicate = try? manager.container.viewContext.count(for: request)) ?? 0