I had to resort to two separate fetches in order to achieve (I think) what you want. The first fetch gets objectIDs for one object for each distinct combination of country
and city
. The second fetch is filtered, using an IN
predicate, to just these objects. It uses NSExpression
and propertiesToGroupBy
to get the counts for each country
:
// Step 1, get the object IDs for one object for each distinct country and city
var objIDExp = NSExpression(expressionType: NSExpressionType.EvaluatedObjectExpressionType)
var objIDED = NSExpressionDescription()
objIDED.expression = objIDExp
objIDED.expressionResultType = .ObjectIDAttributeType
objIDED.name = "objID"
var fetch = NSFetchRequest(entityName: "Location")
fetch.propertiesToFetch = [objIDED]
fetch.propertiesToGroupBy = ["country", "city"]
fetch.resultType = .DictionaryResultType
let results = self.managedObjectContext!.executeFetchRequest(fetch, error: nil)
// extract the objectIDs into an array...
let objIDArray = (results! as NSArray).valueForKey("objID") as! [NSManagedObjectID];
// Step 2, count using GROUP BY
var countExp = NSExpression(format: "count:(SELF)")
var countED = NSExpressionDescription()
countED.expression = countExp
countED.expressionResultType = .ObjectIDAttributeType
countED.name = "count"
var newFetch = NSFetchRequest(entityName: "Location")
newFetch.predicate = NSPredicate(format: "SELF IN %@", objIDArray)
newFetch.propertiesToFetch = ["country", countED]
newFetch.propertiesToGroupBy = ["country"]
newFetch.resultType = .DictionaryResultType
let newResults = self.managedObjectContext!.executeFetchRequest(newFetch, error: nil)
println("\(newResults!)")
This will be inefficient: if you have a large number of distinct countries and cities, the IN predicate will slow things down. You might find it's more efficient to fetch everything and count them.