SwiftData errors when trying to insert multiple objects

I have two models:

@Model
class User: Codable {
    @Attribute(.unique) var username: String
    @Attribute(.unique) var email: String
    var firstName: String
    var lastName: String
    @Attribute(.unique) var id: Int
    @Relationship(inverse: \House.members) var houses: [House] = []
    
    init(username: String, email: String, firstName: String, lastName: String, id: Int) {
        self.username = username
        self.email = email
        self.firstName = firstName
        self.lastName = lastName
        self.id = id
    }
    
    enum CodingKeys: String, CodingKey {
        case username
        case email
        case firstName = "first_name"
        case lastName = "last_name"
        case id
    }
    
    required init(from decoder: Decoder) throws {
        ...
    }
    
    func encode(to encoder: Encoder) throws {
        ...
    }
}

and

@Model
class House: Codable {
    var name: String
    var city: String
    var address: String
    @Attribute(.unique) var id: Int
    var ownerID: Int
    var members: [User]
    
    init(name: String, city: String, address: String, id: Int, ownerID: Int, members: [User]) {
        self.name = name
        self.city = city
        self.address = address
        self.id = id
        self.ownerID = ownerID
        self.members = members
    }
    
    enum CodingKeys: String, CodingKey {
        case name
        case city
        case address
        case id
        case ownerID = "owner_id"
        case members
    }
    
    required init(from decoder: Decoder) throws {
        ...
    }
    
    func encode(to encoder: Encoder) throws {
        ...
    }
}

I want to save a list of House objects I receive in JSON format:

[
  {
    "name": "A",
    "city": "A",
    "address": "A",
    "id": 1,
    "owner_id": 1,
    "members": [
      {
        "username": "A",
        "email": "A",
        "first_name": "A",
        "last_name": "A",
        "id": 1
      }
    ]
  }
  ...
]

This is the code I use:

import SwiftUI
import SwiftData

struct HouseListView: View {
    @Environment(\.modelContext) var modelContext
    @Query(sort: \House.name) var houses: [House]
    
    var body: some View {
        NavigationStack {
            List {
                ForEach(houses) { house in
                    Text(house.name)
                }
            }
            .task {
                if let houses = await getHouses() {
                    do {
                        for house in houses {
                            modelContext.insert(house)
                        }
                        try modelContext.save()
                    } catch {
                        print(error)
                    }
                }
            }
        }
    }
}

But I receive the following errors:

Error Domain=NSCocoaErrorDomain Code=1560 "Multiple validation errors occurred." UserInfo={NSDetailedErrors=(
    "Error Domain=NSCocoaErrorDomain Code=1570 \"%{PROPERTY}@ is a required value.\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x2827cc8c0> (entity: User; id: 0x2804967e0 <x-coredata:///User/tAC4F0253-65B0-4C92-846F-8E72A8E115277>; data: {\n    email = nil;\n    firstName = nil;\n    houses =     (\n    );\n    id = nil;\n    lastName = nil;\n    username = nil;\n}), NSLocalizedDescription=%{PROPERTY}@ is a required value., NSValidationErrorKey=email, NSValidationErrorValue=null}",
    "Error Domain=NSCocoaErrorDomain Code=1570 \"%{PROPERTY}@ is a required value.\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x2827cc8c0> (entity: User; id: 0x2804967e0 <x-coredata:///User/tAC4F0253-65B0-4C92-846F-8E72A8E115277>; data: {\n    email = nil;\n    firstName = nil;\n    houses =     (\n    );\n    id = nil;\n    lastName = nil;\n    username = nil;\n}), NSLocalizedDescription=%{PROPERTY}@ is a required value., NSValidationErrorKey=firstName, NSValidationErrorValue=null}",
    "Error Domain=NSCocoaErrorDomain Code=1570 \"%{PROPERTY}@ is a required value.\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x2827cc8c0> (entity: User; id: 0x2804967e0 <x-coredata:///User/tAC4F0253-65B0-4C92-846F-8E72A8E115277>; data: {\n    email = nil;\n    firstName = nil;\n    houses =     (\n    );\n    id = nil;\n    lastName = nil;\n    username = nil;\n}), NSLocalizedDescription=%{PROPERTY}@ is a required value., NSValidationErrorKey=id, NSValidationErrorValue=null}",
    "Error Domain=NSCocoaErrorDomain Code=1570 \"%{PROPERTY}@ is a required value.\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x2827cc8c0> (entity: User; id: 0x2804967e0 <x-coredata:///User/tAC4F0253-65B0-4C92-846F-8E72A8E115277>; data: {\n    email = nil;\n    firstName = nil;\n    houses =     (\n    );\n    id = nil;\n    lastName = nil;\n    username = nil;\n}), NSLocalizedDescription=%{PROPERTY}@ is a required value., NSValidationErrorKey=lastName, NSValidationErrorValue=null}",
    "Error Domain=NSCocoaErrorDomain Code=1570 \"%{PROPERTY}@ is a required value.\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x2827cc8c0> (entity: User; id: 0x2804967e0 <x-coredata:///User/tAC4F0253-65B0-4C92-846F-8E72A8E115277>; data: {\n    email = nil;\n    firstName = nil;\n    houses =     (\n    );\n    id = nil;\n    lastName = nil;\n    username = nil;\n}), NSLocalizedDescription=%{PROPERTY}@ is a required value., NSValidationErrorKey=username, NSValidationErrorValue=null}",
    "Error Domain=NSCocoaErrorDomain Code=1570 \"%{PROPERTY}@ is a required value.\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x2827cca00> (entity: User; id: 0x280496a80 <x-coredata:///User/tAC4F0253-65B0-4C92-846F-8E72A8E115279>; data: {\n    email = nil;\n    firstName = nil;\n    houses =     (\n    );\n    id = nil;\n    lastName = nil;\n    username = nil;\n}), NSLocalizedDescription=%{PROPERTY}@ is a required value., NSValidationErrorKey=email, NSValidationErrorValue=null}",
    "Error Domain=NSCocoaErrorDomain Code=1570 \"%{PROPERTY}@ is a required value.\" UserInfo={NSValidationErrorObject=<NSManagedObject: 0x2827cca00> (entity: User; id: 0x280496a80 <x-coredata:///User/tAC4F0253-65B0-4C92-846F-

.....


)}
ForEach<Array<House>, Int, Text>: the ID 3 occurs multiple times within the collection, this will give undefined results!

Were you able to solve this? I am having the same issue!

Some ideas:

  • Verify there isn't already an item with id: 1 when re-running mock code
  • Verify anything with @Attribute(.unique) is ACTUALLY unique in mock code
  • Make sure that any models that have a @Relationship have a corresponding deleteRule, if you're running a series of delete(...) elsewhere.

The first one caught me off guard -- if running a series of delete calls on PersistentModel types, make sure that any models that have a @Relationship also have a corresponding deleteRule. When deleting from either end, SwiftData can null out the child in its parent (.nullify), or delete its parent altogether (.cascade). Without this, a hanging reference will be left, causing null value errors.

For example:

@Model 
struct Aisle {
    @Relationship(deleteRule: .nullify, inverse: \Item.aisle)
    var items: [Item]
}

@Model
struct Item {
    @Relationship(deleteRule: .nullify) // works!
    var aisle: Aisle
}

Also, save the model context before running deletes. Otherwise, changes will be flushed from the cache after the delete is ran, causing persistence issues. The joy of caching!

when you save the house the array with members has to be empty. After the house is saved you can append the members like this ...

.task {
                if let houses = await getHouses() {
                    do {
                        for house in houses {
                            modelContext.insert(house)
                            try modelContext.save()
                            // you need a var/let variable, that contains the members of this house somewhere separate from the house object
                            // append members to house after house is saved
                            house.members.append(contentsOf: members)
                        }
                    } catch {
                        print(error)
                    }
                }
            }
SwiftData errors when trying to insert multiple objects
 
 
Q