Search code examples
swiftcore-datanspredicateexecutefetchrequest

Fetching child sum from Core Data


Lets say I have three Entitys. Person: name address (to-many-salary) and (to-many-loans)

Salary: income tax Rel: (to-one-Person)

Bills amount Rel: (to-one-person)

How do I perform a fetch that have a result like this:

John Doe, SUM>income, SUM>amount Eva Doe, SUM>income, SUM>amount

Using Swift


Solution

  • This is probably most easily done using Key Value Coding "collection operators" (see here) rather than a fetch. For each person:

    let name = person.name
    let totalIncome = person.valueForKeyPath("[email protected]")
    let totalLoans = person.valueForKeyPath("[email protected]")
    

    If performance is an issue, you might improve things by amending the fetch request (for the Person objects) to "prefetch" the related Salary and Bills objects:

    fetchRequest.relationshipKeyPathsForPrefetching = ["salary", "loans"]
    

    Alternatively, it is possible to retrieve the required information all in one fetch, though I do not recommend it because it requires changing the fetchRequest to return an array of dictionaries rather than an array of NSManagedObjects. This makes subsequent processing (eg. populating your table view) more difficult.

    // Define NSExpression and NSExpressionDescription for the total income
    let incomeED = NSExpressionDescription()
    incomeED.expression = NSExpression(forKeyPath: "[email protected]")
    incomeED.name = "totalIncome"
    incomeED.expressionResultType = .Integer64AttributeType
    // Define NSExpression and NSExpressionDescription for the total amount
    let amtED = NSExpressionDescription()
    amtED.expression = NSExpression(forKeyPath: "[email protected]")
    amtED.name = "totalLoans"
    amtED.expressionResultType = .Integer64AttributeType
    // specify attributes and expressions to fetch
    fetchRequest.propertiesToFetch = ["name", incomeED, amtED]
    // specify dictionary return type (required to process NSExpressions)
    fetchRequest.resultType = .DictionaryResultType
    

    The result of the fetch will be an array of dictionaries; each dictionary will have keys "name", "totalIncome" and "totalLoans" (with corresponding values).