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
- Week One
- Week Two
- Week Three
Program 2
- Week One A
- Week Two A
- 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)
}
}