您可以使用 NSExpression 类从 CoreData 获取聚合信息。这是我专门为您的案例创建的示例,因为我以前从未这样做过并且发现这很有趣;)
我的 CoreData 模型如下所示:
对于 Animal 的类型我使用枚举:
enum AnimalType: Int {
case Cat, Dog
}
视图控制器的代码:
class AggregationResult {
let locationName: String
let animalType: AnimalType
let count: Int
init(locationName: String, animalType: AnimalType, count: Int) {
self.locationName = locationName
self.animalType = animalType
self.count = count
}
}
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
private var dataSource: [AggregationResult] = []
override func viewDidLoad() {
super.viewDidLoad()
load()
}
private func load() {
let countExpressionDesc = NSExpressionDescription()
countExpressionDesc.name = "countAnimals"
countExpressionDesc.expression = NSExpression(forFunction: "count:", arguments: [NSExpression(forKeyPath: "type")])
countExpressionDesc.expressionResultType = .Integer32AttributeType
let request = NSFetchRequest(entityName: "Animal")
request.propertiesToFetch = ["location.name", "type", countExpressionDesc]
request.propertiesToGroupBy = ["location.name", "type"] // <-- all these properties should be put in 'propertiesToFetch' otherwise we will have crash
//request.predicate = NSPredicate(format: "location.name == %@", argumentArray: ["Oregon"]) // <-- uncomment to find animals from Oregon only
request.resultType = .DictionaryResultType
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let results = try! appDelegate.managedObjectContext.executeFetchRequest(request)
if let results = results as? [NSDictionary] {
print("results: \(results)")
for dict in results {
if let
name = dict["location.name"] as? String,
type = dict["type"] as? Int,
atype = AnimalType(rawValue: type),
count = dict["countAnimals"] as? Int {
let ar = AggregationResult(locationName: name, animalType: atype, count: count)
dataSource.append(ar)
}
}
tableView.reloadData()
}
}
}
extension ViewController: UITableViewDataSource {
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
let item = dataSource[indexPath.row]
cell.textLabel!.text = "\(item.locationName)"
cell.detailTextLabel!.text = "\(item.count) \(item.animalType == .Cat ? "cats" : "dogs")"
return cell
}
}
你感兴趣的获取放在load函数中。
最后我得到的结果是:
results: [{
countAnimals = 60;
"location.name" = California;
type = 0;
}, {
countAnimals = 150;
"location.name" = California;
type = 1;
}, {
countAnimals = 100;
"location.name" = Oregon;
type = 0;
}, {
countAnimals = 200;
"location.name" = Oregon;
type = 1;
}]
表格看起来像:
希望这会有所帮助:)