Camile
Camile

Reputation: 175

Check if Realm data has been added on a specific date

I am trying create a lookup if there is any workout registered on a specific date.

The Object class looks like this:

class Workout: Object {

    @objc dynamic var date: Date?
    // List of exercises (to-many relationship)
    var exercises = List<Exercise>()

}

And

class Exercise: Object {

    @objc dynamic var name: String?
    // List of sets (to-many relationship)
    var sets = List<Set>()
    var parentWorkout = LinkingObjects(fromType: Workout.self, property: "exercises")
}

In Realm, I can see that there is one registered with the date 2019-12-07 19:48:35 +0000;. So I am adding a check in my viewDidLoad like this:

let nowDate = Date()
func checkIfWorkoutHasBeenRegistered() {// Check if there already exist a workout today
        let realm = try! Realm()

        let todaysWorkouts = realm.objects(Workout.self).filter("date = %@", nowDate)
        if todaysWorkouts.isEmpty {
            print("No workout found")
        } else {
            print("Workout has been created")
        }
    }

But it gives me output No workout found, even thought I have registered a workout today. Any tips?

Upvotes: 0

Views: 1517

Answers (2)

Jay
Jay

Reputation: 35657

This may or may not be applicable but there is some complexity in working with a Date object in its pure form.

As shown in your question for example, what if you want to get a workout for 12/09/2019? Or, get ALL workouts on a date. If you generate a date object for the date you want to filter for like this

var dateComps = DateComponents()
dateComps.day = 08
dateComps.month = 12
dateComps.year = 2019
let cal = Calendar.current
let theDate = cal.date(from: dateComps)

there's also a time component to factor in so this will query will not work

let workoutResults = realm.objects(Workout.self).filter("timestamp == %d", theDate)

because the date object stored in Realm is this

2019-12-08T15:32:40

and your query is for this

2019-12-08T05:00:00

note that even though the DAY is the same the TIME is different so no match. You could craft a range filter for any results between 12AM and 11:59 PM but again, may be overly complex.

It comes down to if you need the time portion of the date. If not, how about this model

class Workout: Object {
    @objc dynamic var workout_id = UUID().uuidString

    @objc dynamic var date_stamp: String?
    @objc dynamic var workout_name: String?
    @objc dynamic var timestamp: Date?

    convenience init(withName: String) {
        self.init()
        let date = Date()
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyyMMdd"
        let result = formatter.string(from: date)

        self.date_stamp = result
        self.workout_name = withName
        self.timestamp = date
    }

    var exercises = List<Exercise>()

    override static func primaryKey() -> String? {
        return "workout_id"
    }
}

and you get the best of both as your workout now has a name, a searchable and sortable date string and an actual time stamp if needed.

name: "Monday Workout"
date_stamp: "20191208"
timestamp: 2019-12-08T15:32:40

So the filter for a particular date becomes

let workoutResults = realm.objects(Workout.self).filter("date_stamp == '20191208'")

Upvotes: 0

beyowulf
beyowulf

Reputation: 15331

With your current predicate you're comparing the save date and time to current date and time which are certainly going to be different because even a fraction of a second difference is going to make them unequal. Instead you likely want to see if the saved date falls within a some range. For example, if you wanted to see all objects that have a date that occurred "today," you could create a predicate like:

let startOfDay = Calendar.current.startOfDay(for: Date())
let endOfDay = Calendar.current.date(byAdding: .day, value: 1, to: startOfDay) ?? Date()

let predicate = NSPredicate(format: "date >= %@ && date < %@", startOfDay as NSDate, endOfDay as NSDate)
let todaysWorkouts =  realm.objects(Workout.self).filter(predicate)

Upvotes: 2

Related Questions