'How to sum the numbers(Int16) of stored core data - Swift 3

I have stored the letters(String), numbers(Int16) and Date(Date) in the core data. And the filter(NSPredicate) succeeded in organizing only the necessary data.

I want to get the total sum of the numbers in this core data.

  • Entity Name : Entity
  • Attribute Name : Letter(String), Value(Int16), Date(Date)

let context = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext

let entityDesc: NSEntityDescription = NSEntityDescription.entity(forEntityName: "Entity", in: context)!

let request: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest()

request.entity = entityDesc

// Omit date NSFormatter

let dateCheck = formatter.string(from: today)

request.predicate = NSPredicate(format: "Date == %@", dateCheck)

let records = try! context.fetch(request)

I do not know what to do next. I am a beginner in development and hope someone can help.



Solution 1:[1]

You have already fetch the records, so get the sum of the Value attribute this way.

try! context.fetch(request) as! [NSManagedObject]
let sum = result.reduce(0) { $0 + ($1.value(forKey: "Value") as? Int16 ?? 0) }
print(sum)

Solution 2:[2]

The approuved answer is not realy using coreData feature of aggregation

This is complete answer and ready to use, as developers like Haha:


extension NSManagedObject {
    
    static var className: String {
        String(describing: Self.self)
    }
}

class MyModelDAO {

    /// col: name of colum to sum, like `numberOrLikes: Int32`
    func getSumBy<T: NSManagedObject>(model: T.Type, col: String) throws -> Int32? {
        
        let request = NSFetchRequest<NSFetchRequestResult>.init(entityName: model.className)

        let sumDesc = NSExpressionDescription()
        sumDesc.name = "sum"
        
        let keypathExp1 = NSExpression(forKeyPath: col)
        let expression = NSExpression(forFunction: "\(sumDesc.name):", arguments: [keypathExp1])
        sumDesc.expression = expression
        sumDesc.expressionResultType = .integer64AttributeType
        
        request.returnsObjectsAsFaults = false
        request.propertiesToFetch = [sumDesc]
        request.resultType = .dictionaryResultType
        
        let result = try context.fetch(request) as? [[String: Any]]
        
        return result?.first?[sumDesc.name] as? Int32
    }
}

How to use it:


  let result = try self.getSumBy(model: User.self, col: "myColumn")
  print(result)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nirav D
Solution 2 Siempay