13

I'm building an app using Swift with Core Data. At one point in my app, I want to have a UITableView show all the objects of a type currently in the Persistent Store. Currently, I'm retrieving them and showing them in the table view using an NSFetchedResultsController. I want the table view to be sorted by a computed property of my NSManagedObject subclass, which looks like this:

class MHClub: NSManagedObject{
@NSManaged var name: String
@NSManaged var shots: NSSet
var averageDistance: Int{
    get{
        if shots.count > 0{
            var total = 0
            for shot in shots{
                total += (shot as! MHShot).distance.integerValue
            }
            return total / shots.count
        }
        else{
            return 0
        }
    }
}

In my table view controller, I am setting up my NSFetchedResultsController's fetchRequest as follows:

let request = NSFetchRequest(entityName: "MHClub")
request.sortDescriptors = [NSSortDescriptor(key: "averageDistance", ascending: true), NSSortDescriptor(key: "name", ascending: true)]

Setting it up like this causes my app to crash with the following message in the log:

'NSInvalidArgumentException', reason: 'keypath averageDistance not found in entity <NSSQLEntity MHClub id=1>'

When I take out the first sort descriptor, my app runs just fine, but my table view isn't sorted exactly how I want it to be. How can I sort my table view based on a computed property of an NSManagedObject subclass in Swift?

Michael Hulet
  • 3,253
  • 1
  • 16
  • 33
  • 5
    A Core Data fetch request *cannot* sort on a computed property, only on persistent stored properties. Compare (for example) http://stackoverflow.com/questions/13325849/sorting-on-transient-fields-with-nsfetchedresultcontroller. – Martin R May 08 '15 at 19:35
  • Also, your `total` is inferred to be int, so the average will be wrong. E.g. shots 1,1,3 = 5/3 = 1. – Mundi May 08 '15 at 23:50

1 Answers1

8

As was pointed out by Martin, you cannot sort on a computed property. Just update a new stored property of the club every time a shot is taken.

Mundi
  • 79,884
  • 17
  • 117
  • 140