Create a func which totals the value of data

I created a core data data model and now I want to total/sum one of the attributes. The data model is as follows:

import CoreData
@objc(Aktie)
class Aktie: NSManagedObject
{
    @NSManaged var deletedDate: Date?
    @NSManaged var id: NSNumber!
    @NSManaged var title: String?
    @NSManaged var point: String?
}

The code for the ViewController to show the total is:

import UIKit
import CoreData

var points = [Aktie]()
var firstLoad = true

class TotalPointsViewController: UIViewController {
    @IBOutlet weak var totalPoints: UILabel!  
    
override func viewDidLoad() {
        super.viewDidLoad()
        if(firstLoad)
    {
            firstLoad = false
            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            let context: NSManagedObjectContext = appDelegate.persistentContainer.viewContext
            let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Aktie")
            do {
                let results: NSArray = try context.fetch(request) as NSArray
                for result in results {
                    let aktie = result as! Aktie
                    points.append(aktie)
                }
            }
            catch
            {
                print("Fetch Failed")
            }
        }
    }
    // Mark: Add total of points
   func calculateSumPoints() -> [Aktie] {
    let sum = 0
    for punt in points.point {
        sum += Int(punt)
     }
    totalPoints.text = "\(sum)"
    }
}

What am I doing wrong?

What is the problem ? Does not compile ? Wrong result ?

I see a first issue:

     func calculateSumPoints() -> [Aktie] {
          let sum = 0
          for punt in points.point {
               sum += Int(punt)
          }
          totalPoints.text = "\(sum)"
     }
  • calculateSumPoints does not return any value. It should return an [Aktie] array

Do you mean ?

func calculateSumPoints()  {

Other issues:

          for punt in points.point {
  • points is [Aktie]. As such, it has no point property

  • sum is a constant, you cannot add to it

  • point is optional : need to unwrap

  • Int(string) is optional, must be unwrapped

So, likely code should be

     func calculateSumPoints() {
          var sum = 0
          for punt in points {
               sum += Int(punt.point ?? "0") ?? 0
          }
          totalPoints.text = "\(sum)"
     }

Note: in Swift, no parenthesis needed, just write

          if firstLoad {

Because you're calling your code in the viewDidLoad override, firstLoad is not required. The viewDidLoad only gets called once and only once per instance. firstLoad and points: [Atkie]() should be instances of the view controller and not globals.

One of the nice things about swift are its high order functions. The calculateSumPoints method can be rewritten as follows:

func calculateSumPoints() {
    let sum = points.compactMap { $0.point } // this remove any nil point string values from the collection
        .reduce(0) { previous, next in // using reduce we access to the previous and current value
            guard let value = Int(next) else { return previous } // unwrap next as an Int if it fails return the previous calculation
            return previous + value // return the sum of the previous value and the next value
        }
     totalPoints.text = "\(sum)" 
 }

I have tried the code in both answers - I also positioned the code where I calculate the total points between various brackets but it is not showing any results in my viewcontroller. There are no coding errors in both solutions. There is data in my records.

import CoreData

class TotalPointsViewController: UIViewController {

    @IBOutlet weak var totalPoints: UITextField!
    var points = [Aktie]()
    var firstLoad = true

    override func viewDidLoad() {
        super.viewDidLoad()
      if firstLoad
        {
            firstLoad = false
            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            let context: NSManagedObjectContext = appDelegate.persistentContainer.viewContext
            let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Aktie")
            do {
                let results: NSArray = try context.fetch(request) as NSArray
                for result in results {
                    let aktie = result as! Aktie
                    points.append(aktie)
                }
            }
            catch
            {
                print("Fetch Failed")
            }
       }
   }

       func calculateSumPoints() {
        let sum = points.compactMap { $0.point } 
            .reduce(0) { previous, next in 
                guard let value = Int(next) else { return previous } 
                return previous + value 
            }

        totalPoints.text = "\(sum)"

    }

}

This code gives me the result of savings but is also adding deleted records to the total point? How do I prevent deleted records to be added to the total.

import UIKit
import CoreData
class TotalPointsViewController: UIViewController {
var points = [Aktie]()
    @IBOutlet weak var totalPoints: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()         

            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            let context: NSManagedObjectContext = appDelegate.persistentContainer.viewContext
            let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Aktie")
            do {
            let points: NSArray = try context.fetch(request) as NSArray
            var sum = 0
            for result in points {
                sum += Int((result as AnyObject).point ?? "0") ?? 0
            }
            totalPoints.text = "\(sum)"
        }
        catch {
            print("Fetch Failed")
        }
    }
}

It is not cl.

When you delete records, do you really delete them from coreData database ?

It seems no.

Create a func which totals the value of data
 
 
Q