0

self-learning beginner here. I am trying to show an Int from Core Data in a VStack in ContentView, not in a List. But literally all the tutorials I can find about Core Data (tracking Books, Movies, Orders, Students) are using a List to show an array containing an Int. Nothing on showing an Int by itself.

Xcode can build countnum.countnum +=1 with no problem. Seems to me it is reading it fine. But once I try to show it, it just doesn’t work. I’m wrecking my brain here.

struct ContentView: View {
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(sortDescriptors: []) var countnum: FetchedResults<CountNum>
    
    var body: some View {
//        let countnum = CountNum(context: moc)
        VStack{
            Text("+")
                .padding()
                .onTapGesture (count: 2){
                    let countnum = CountNum(context: moc)
                    countnum.countnum += 1
                }
            Text("\(countnum)") //No exact matches in call to instance method 'appendInterpolation'
        }
        
        
    }
}

enter image description here

Thanks

Walter Pak
  • 79
  • 7
  • Look at the sheet [here](https://stackoverflow.com/questions/69330564/use-the-same-view-for-adding-and-editing-coredata-objects/69330873#69330873) – lorem ipsum Jan 18 '22 at 00:52
  • @loremipsum Thank you for the answer. But I gotta be honest. The code there looks way above my current (close to non-exist) ability to read code. – Walter Pak Jan 18 '22 at 15:36
  • @loremipsum If I try my best to understand it. The .sheet has an action $vm.newItem . Are you say I need to add an item in my entity? – Walter Pak Jan 18 '22 at 15:38
  • No the `sheet(item)` is triggered when `@Published var newItem: Item? = nil` is `!=` to `nil`. The `Button` with `vm.addItem(moc: viewContext)` creates a new object then puts the object on the `newItem`. The sheet then opens with the new object. `Item` is just the sample entity that comes with a new Xcode project. You can take that code and paste it in one so you can see how it works. – lorem ipsum Jan 18 '22 at 16:47

1 Answers1

1

....all the tutorials ... show an array containing an Int. Yes, that's because CoreData can contain many "objects". You get an array of your CountNum objects when you do your .....var countnum: FetchedResults<CountNum>. So you need to decide which CountNum you want to use. For example, if you want to use the first one, then:

struct ContentView: View {
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(sortDescriptors: []) var countnum: FetchedResults<CountNum>
    
    var body: some View {
        VStack {
            if let firstItem = countnum.first {
                Text("+")
                    .padding()
                    .onTapGesture(count: 2) {
                        firstItem.countnum += 1
                        do {
                            try moc.save()
                        } catch {
                            print(error)
                        }
                    }
                Text("\(firstItem.countnum)").foregroundColor(.green)
            }
        } 
    }
}

EDIT-1: adding new CountNum to CoreData example code in the add button.

struct ContentView: View {
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(sortDescriptors: []) var countnum: FetchedResults<CountNum>
    
    var body: some View {
        Button(action: {add()}) { Text("add new CountNum").foregroundColor(.green) }
        .padding(.top, 50)
        List {
            ForEach(countnum) { item in
                HStack {
                    Text("++")
                        .onTapGesture(count: 2) { increment(item) }
                    Text("\(item.countnum)").foregroundColor(.blue)
                    Text("delete").foregroundColor(.red)
                        .onTapGesture { delete(item: item) }
                }
            }
        }
    }
    
    func increment(_ item: CountNum) {
        item.countnum += 1
        save()
    }
    
    func add() {
        let countnum = CountNum(context: moc)
        countnum.countnum = 0
        save()
    }
    
    func delete(item: CountNum) {
        moc.delete(item)
        save()
    }
    
    func save() {
        do { try moc.save() } catch { print(error) }
    }
    
}
  • Thank you so much. This is exaclty what I had in mind. Just one single int. The code works when I run it. But for some reason there is nothing shown but a blank sheet on the simulator. Any quick thought? https://imgur.com/a/eKiw60P – Walter Pak Jan 18 '22 at 15:30
  • yes, it's probably because you do not have any data in your CoreData. You can easily add some using the EDIT-1 code in my updated answer. If this answer your questions, please consider marking my answer as correct, thank you. – workingdog support Ukraine Jan 18 '22 at 23:17