Reputation: 559
I'm trying to count the number of exercises in a Realm List (contained within a "WorkoutSessionObject") to populate the right number of rows for a tableview but for some reason I can't work out it isn't letting me access the property?
It's definitely retrieving the WorkoutSessionObject because I've tried printing it.
Here's the code :
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//filter for a specific workout
let predicate = NSPredicate(format: "workoutID = %@", workoutID)
let workoutExercises = realm.objects(WorkoutSessionObject.self).filter(predicate)
//access the 'exercises' list and count it - this isn't working?
let numberOfExercises = workoutExercises.exercises.count
return numberOfExercises
}
I've accessed the properties in a similar way for populating the cells but I'm obviously using index.row there.
The error I'm getting is
Value of type 'Results' has no member 'exercises'
on the line that is marked as not working in the code
Research there is an answer here Retrieve the List property count of realm for tableview Swift but that doesn't seem it would return the count in scope (it allows a print in the example but this isn't working in my code)
i.e. I've also tried this, which doesn't work because the count isn't accessible outside the scope :
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let predicate = NSPredicate(format: "workoutID = %@", workoutID)
//the below works to count but then not accessible outside scope to define number of rows :-(
let workoutExercises = realm.objects(WorkoutSessionObject.self).filter(predicate)
for exercises in workoutExercises {
let exerciseCount = exercises.exercises.count
return exerciseCount
}
//return exercise count for table rows - this doesn't work because not in scope
return exerciseCount
}
Any ideas?
Upvotes: 0
Views: 3178
Reputation: 54706
The issue is that Realm's filter
keeps the original type (just like Swift's built-in filter
), so the type of workoutExercises
will actually be Results<WorkoutSessionObject>
and not a single WorkoutSessionObject
.
If you know that the workoutID
property of the WorkoutSessionObject
is always unique, you can simply call first
on the Results
instance.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let predicate = NSPredicate(format: "workoutID = %@", workoutID)
let workoutExercises = realm.objects(WorkoutSessionObject.self).filter(predicate).first
return workoutExercises?.exercises.count ?? 0
}
If you know that there will always be a matching WorkoutSessionObject
, you can force unwrap workoutExercises
.
If workoutID
is actually a primaryKey, its even better to use let workoutExercises = realm.object(ofType: WorkoutSessionObject.self, forPrimaryKey: workoutID)
instead of the filtered query.
Upvotes: 2