0

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

  • 1
    Remove the managed it is just a computed property – lorem ipsum Dec 10 '22 at 17:58
  • @loremipsum thank you. I did what you suggested. Then I have added: Text(String($player.scoretotal)) in my VStack And I have two error messages saying: - Cannot assign to property: 'scoretotal' is a get-only property - Initializer 'init(_:)' requires that 'Binding' conform to 'LosslessStringConvertible' – user20587286 Dec 10 '22 at 19:58
  • Remove the dollar sign, binding is for when you need a two way connection. – lorem ipsum Dec 10 '22 at 20:07
  • @loremipsum thank you. I did what you suggested. Then I have added Text(String(player.scoretotal)) in my VStack, and it works like a charm! Thanks again – user20587286 Dec 10 '22 at 20:09
  • If I answered your question do you mind clicking on the green checkmark below to mark the answer as accepted – lorem ipsum Dec 13 '22 at 14:22

1 Answers1

0

Remove

@NSManaged

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

lorem ipsum
  • 21,175
  • 5
  • 24
  • 48
  • Hi @lorem ipsum I have posted an other question on the same project. If you have a few minutes I would appreciate you having a look. Thank you: https://stackoverflow.com/questions/74883410/a-coredata-computed-property-used-to-sort-an-array-of-object-is-not-updated-wor – user20587286 Dec 22 '22 at 20:51
  • @user20587286 I saw that earlier. That is a lot of code to weed through but you can look at [this](https://stackoverflow.com/questions/58845896/swiftui-fetchrequest-core-data-changes-to-relationships-dont-refresh/70959918#70959918) the answer with the bounty there should help you find a workaround. It isn’t ideal but it is a complete setup for something similar. – lorem ipsum Dec 22 '22 at 21:48
  • Hi @lorem ipsum and thanks for pointing me to that other thread. I tried to understand it and to make some changes in my code but I don't have the coding ability to implement it in my code... To me it doesn't make sense that the computed property is not updated even though other properties are correctly updated. – user20587286 Dec 23 '22 at 03:33