Search code examples
swiftuicore-dataattributescalculation

In swifUI, for a given entity in CoreData, can I have an attribute that is the sum of other attributes of that entity?


I have a Coredata entity called Players, which as the following attributes:

  • name (of type String)
  • scorelevel1 (of type Integer16)
  • scorelevel2 (of type Integer16)
  • scorelevel3 (of type Integer16)
  • scoretotal (of type Integer16)

I would like the scoretotal to be the sum of scorelevel1 + scorelevel2 + scorelevel3

Is it possible to do so?

My Model is like that:

extension Players {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Players> {
        return NSFetchRequest<Players>(entityName: "Players")
    }

    @NSManaged public var name: String?
    @NSManaged public var scorelevel1: Int16
    @NSManaged public var scorelevel2: Int16
    @NSManaged public var scorelevel3: Int16
    @NSManaged public var scoretotal: Int16
    
    public var wrappedName: String {
        name ?? "player unknown"
    }
}

extension Players : Identifiable {

}

then I have a MainUIView which calls a PlayerView (see below), where I want to be able to enter the scores of each player for each level, and I would like to automatically sum the score of each level and store that totalscore in my coredata attribute "scoretotal":

The MainUIView is like this:

struct MainUIView: View {
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Players.entity(), sortDescriptors: [
        NSSortDescriptor(keyPath: \Players.name, ascending: false)
    ]) var players: FetchedResults<Players>

    var body: some View {
          HStack{
                 ForEach(players, id: \.wrappedName) { player in
                       PlayerView(player: player)
                 }
          }
}

and the PlayerView is like this:

struct PlayerView: View {

    @ObservedObject var player:Players
    @Environment(\.managedObjectContext) var moc

    var body: some View {

        VStack {
            Text(player.wrappedName)
            TextField("Score", value: $player.scorelevel1, formatter:NumberFormatter())
            TextField("Score", value: $player.scorelevel2, formatter:NumberFormatter())
            TextField("Score", value: $player.scorelevel3, formatter:NumberFormatter())
        }
    }
}

**What I would like to add is a "text", on the last row of the VStack which would be the sum of $player.scorelevel1 + $player.scorelevel2 + $player.scorelevel3

and store it in $player.scoretotal**

I am new at SwiftUI and I can't figure out how to do that. I tried to declare a var in PlayerView like this:

    var total: Int16 {
        $player.scorelevel1 + $player.scorelevel2 + $player.scorelevel3
        }

but I have an error message saying: "Binary operator '+' cannot be applied to two 'Binding' operands" and "No '+' candidates produce the expected contextual result type 'Int16'"

Anyway, it doesn't look like the right way to do it and even if it works I wouldn't know how to assign that variable "total" to "$player.scoretotal"...

I also tried to declare a computed property in my model, by doing:

    @NSManaged public var scoretotal: Int16 {
        scorelevel1 + scorelevel2 + scorelevel3
    }

but I have the error message saying "@NSManaged not allowed on computed properties"

I would be very grateful if someone could help me with that. Thanks and regards, JB


Solution

  • Remove

    @NSManaged
    

    To make a regular computer variable. This variable doesn’t need to me managed/storage.