Core Data: Deletion of Entity deletes from a separate instance

Viewed 27

Here's the core data schema:

Program --->> Weeks --->> Days --->> Exercises

I have a problem that when I create a few Weeks within a Program, then create another Program with a few Weeks, deleting a week from one Program will delete from the other Program's Weeks. This also happens within the Days and Exercises.

Maybe my delete function is wrong?

For example:

Program 1

  1. Week One
  2. Week Two
  3. Week Three

Program 2

  1. Week One A
  2. Week Two A
  3. Week Three A

Deleting Week Two A from Program 2 will delete Week Two from Program 1 and so on..

WeekViewModel

import Foundation
import CoreData

class WeekViewModel: ObservableObject {
    
    let manager = PersistenceController.shared
    @Published var weeks: [WeekEntity] = []
    
    init() {
        getWeeks()
    }
    
    func getWeeks() {
        let request = NSFetchRequest<WeekEntity>(entityName: "WeekEntity")
        
        let sort = NSSortDescriptor(key: "id", ascending: true)
        request.sortDescriptors = [sort]
        
        do {
            weeks = try manager.container.viewContext.fetch(request)
        } catch let error {
            print("Error fetching weeks! \(error)")
        }
    }
    
    func addWeek(name: String, program: ProgramEntity) {
        let newWeek = WeekEntity(context: manager.container.viewContext)
        newWeek.name = name
        newWeek.programs = program
        save()
    }
    
    func deleteWeeks(at offsets: IndexSet) {
        for index in offsets {
            let week = weeks[index]
            manager.context.delete(week)
        }
        save()
        getWeeks()
    }
    
    // moveWeek?
    
    func save() {
        manager.save()
    }
}

WeekListView

import SwiftUI
import CoreData

struct WeekListView: View {
    
    @Environment(\.managedObjectContext) private var viewContext
    @EnvironmentObject var weekViewModel: WeekViewModel
    
    var program: ProgramEntity
    
    var body: some View {
        Group {
            if let mulWeeks = program.multipleWeeks?.array as? [WeekEntity] {
                ForEach(mulWeeks, id: \.self) { week in
                    ZStack {
                        Text(week.name ?? "")
                            .font(.system(size: 40, weight: .light, design:.default))
                            .foregroundColor(Color("lightblue"))
                            .padding()
                            .frame(width: 350, height: 60, alignment: .leading)
                            //.overlay(RoundedRectangle(cornerRadius: 20).stroke(Color("lightblue"), lineWidth: 2))
                        
                        NavigationLink(destination: DayView(week: week)) {
                            EmptyView()
                        }
                        .opacity(0.0)
                    }
                }
                .onDelete(perform: weekViewModel.deleteWeeks)
            }
        }
    }
}

struct WeekListView_Previews: PreviewProvider {
    static var previews: some View {
        let context = PersistenceController.shared.container.viewContext
        let program = ProgramEntity(context: context)
        program.name = "Program 2"
        return WeekListView(program: program)
            .previewLayout(.sizeThatFits)
            
            .environmentObject(WeekViewModel())
    }
}

If needed

ProgramsViewModel

import Foundation
import CoreData

class ProgramsViewModel: ObservableObject {

    let manager = PersistenceController.shared
    @Published var programs: [ProgramEntity] = []
    
    
    init() {
        getPrograms()
    }
    
    func getPrograms() {
        let request = NSFetchRequest<ProgramEntity>(entityName: "ProgramEntity")
        //let date = NSDate()
        
        let sort = NSSortDescriptor(key: "id", ascending: true)
        request.sortDescriptors = [sort]
        
        do {
            programs = try manager.container.viewContext.fetch(request)
        } catch let error {
            print("Error fetching programs! \(error)")
        }
        
    }
    
    func addProgram(name: String, weeks: Int64, days: Int64) {
        let newProgram = ProgramEntity(context: manager.container.viewContext)
        newProgram.name = name
        newProgram.weeks = weeks
        newProgram.days = days
        save()
    }
    
    
    
    func deletePrograms(at offsets: IndexSet) {
        for index in offsets {
            let program = programs[index]
            manager.context.delete(program)
        }
        save()
        getPrograms()
    }
    
    func moveProgram(from: IndexSet, to: Int) {
        programs.move(fromOffsets: from, toOffset: to)
        save()
    }
    
    func save() {
        manager.save()
    }
    
    func addWeekProgram(week: WeekEntity) {
        let newWeek = ProgramEntity(context: manager.container.viewContext)
        newWeek.addToMultipleWeeks(week)
        
    }

}

ProgramsListView

import SwiftUI
import CoreData

struct ProgramListView: View {
    
    @Environment(\.managedObjectContext) private var viewContext
    @EnvironmentObject var programsViewModel: ProgramsViewModel
    
    var body: some View {
        workingVStack
        
    }
}

struct ProgramListView_Previews: PreviewProvider {
    static var previews: some View {
        ProgramListView()
            .previewLayout(.sizeThatFits)
            .environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
            .environmentObject(ProgramsViewModel())

    }
}

extension ProgramListView {
    
    private var workingVStack: some View {
        ForEach(programsViewModel.programs, id: \.self) { program in
            ZStack {
                VStack(alignment: .leading) {
                            HStack {
                                Text(program.name ?? "")
                                    .font(.system(size: 40, weight: .light, design: .default))
                                    .foregroundColor(Color("lightblue"))
                                
                            }
                            HStack {
                                Text("Weeks:")
                                    .foregroundColor(.gray)
                                Text("\(program.weeks)")
                                Spacer()
                                Text("Days:")
                                    .foregroundColor(.gray)
                                Text("\(program.days)")
                            }
                            .frame(width: 300)
                }
                NavigationLink(destination: WeekView(program: program)) {
                    EmptyView()
                }
                .opacity(0.0)
            }
        }
        .onDelete(perform: programsViewModel.deletePrograms)
        .onMove(perform: programsViewModel.moveProgram)
    }
}
0 Answers
Related