Search code examples
swiftuicore-data

Add values in a on to many construct but it seems that it would add it with one to one


I have to add types of devices to a manufacturer. The manufacturer name should be unique.

enter image description here

In the relationship i have one to many from the manufacturers to the type and in the opposite I have the relationship many to one from the types to the manufacturers.

Now I try to add with this example some values:

struct ManufacturerListView: View {
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(sortDescriptors: []) var manufacturers: FetchedResults<ManufacturerEntity>
    
    var body: some View {
        VStack {
            List {
                ForEach(manufacturers, id: \.self) { manufacturer in
                    Section(manufacturer.wrapedName) {
                        ForEach(manufacturer.typesArray, id: \.self) { type in
                            Text(type.wrappedNname)
                        }
                    }
                }
            }
            
            Button("Add Examples") {
                let type1 = TypeEntity(context: viewContext)
                type1.name = "T2"
                type1.manufacturer = ManufacturerEntity(context: viewContext)
                type1.manufacturer?.name = "Tormek"
                
                let type4 = TypeEntity(context: viewContext)
                type4.name = "T8"
                type4.manufacturer = ManufacturerEntity(context: viewContext)
                type4.manufacturer?.name = "Tormek"
                
                let type5 = TypeEntity(context: viewContext)
                type5.name = "sh222"
                type5.manufacturer = ManufacturerEntity(context: viewContext)
                type5.manufacturer?.name = "Scheppach"
                
            do {
                let done = try viewContext.save()
            } catch let error {
                let errortext = error.localizedDescription
                print(errortext)
            }
            }
        }
    }
}

But it seems that the manufacturer would added seperate and it be not used as unique.

Where is my mistake? I can't see it.

I got the error:

Error Domain=NSCocoaErrorDomain Code=133021 "(null)" UserInfo={NSExceptionOmitCallstacks=true, conflictList=(
    "NSConstraintConflict (0x600000012d80) for constraint (\n    name\n): database: (null), conflictedObjects: (\n    \"0x6000015353c0 \",\n    \"0x6000015350e0 \"\n)"
)}

enter image description here


Solution

  • It's because of this line:

    try? viewContext.save()
    

    This throws an error, but you don't handle it, so you end up with erroneous results. Your code creates an erroneous situation but ignores the error by using try?.

    When you have a uniqueness constraint like this and your code violates that constraint (as it does here), Core Data has conflicting requirements that need to be resolved somehow.

    If you made it a try instead of a try? and you caught the error, you'd find that the error is an NSConstraintConflict that describes the conflict your code creates. You could have code in the catch block to resolve the conflict.

    You could also choose a merge policy for your context, which would make it resolve the conflict automatically. There are several automatic options-- see the documentation for NSMergePolicy to chose one.