TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

Most efficient way to bind dates to a Core Data entity

Forums > SwiftUI

I am on my way with creating a habit tracking app which uses Core Data for storing the habits. Because I need to know when I completed a part of my habit, I created a different entity containing only a Date with a many to one relationship to the habit entity. So one habit has a reference to many different dates on which it was completed, and the other way around.

First question: Is this the best method for doing this? Because the longer someone uses the app the more cluttered it gets with dates.

Second question: If it is good, how do I count the times I completed some habit for one specific date or a specific time interval (eg. week). I currently just compactMap over an array and count the result, but when having around 150 items in this array, it gets rather slow:

withAnimation(.easeInOut) {
    let todayCount = habit.dateArray.compactMap { (Calendar.current.isDateInToday($0.date!)) }
    return todayCount.count
}

I currently add a Date like this:

let newhabit = HabitCompletionDate(context: viewContext)
newhabit.date = Date()
newhabit.item = habit

And delete like this:

let habitObject = habit.date?.allObjects.last
viewContext.delete(habitObject as! NSManagedObject)

I don´t need the specific time, only the day of completion would still be enough, but this was the only solution I could come up with.

I have seen someone saying that you could do something like this with an NSPredicate but I did not understand how. As you might have guessed by this rather basic questions, I have no real experience in Core Data and personally it often gives me headaches.

Thanks in advance!

2      

I have seen someone saying that you could do something like this with an NSPredicate but I did not understand how.

You would do something like this:

let cal = Calendar.current

//testDate being the date you want to check for
let startDate = cal.startOfDay(for: testDate)
let endDate = cal.date(byAdding: .day, value: 1, to: startDate)

//assuming date is the name of your Core Data attribute
let predicate = NSPredicate(format: "date >= %@ AND date < %@", startDate, endDate)

3      

Okay, that's a good starting point, thank you! How would I go about implementing it? I know I can use it in a fetch request so that would be useful for my List View, but what should I do when I already have my Habit-item, like I do in my DetailView?

2      

Hacking with Swift is sponsored by Blaze.

SPONSORED Still waiting on your CI build? Speed it up ~3x with Blaze - change one line, pay less, keep your existing GitHub workflows. First 25 HWS readers to use code HACKING at checkout get 50% off the first year. Try it now for free!

Reserve your spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.