Is SwiftData's #Unique currently broken or am I missing something?

Hi,

I am inserting two models where the "unique" attribute is the same. I was under the impression, that this should result in an upsert and not two inserts of the model, but that is not the case.

See the test coding below for what I am doing (it is self contained, so if you want to try it out, just copy it into a test target). The last #expect statement fails because of the two inserts. Not sure if this is a bug (Xcode 16 beta 2 on Sonoma running an iOS 18 simulator) or if I am missing something here...

// MARK: - UniqueItem -

@Model
final class UniqueItem {
  #Unique<UniqueItem>([\.no])
  
  var timestamp = Date()
  var title: String
  var changed = false
  var no: Int

  init(title: String, no: Int) {
    self.title = title
    self.no = no
  }
}

// MARK: - InsertTests -

@Suite("Insert Tests", .serialized)
struct InsertTests {
  var sharedModelContainer: ModelContainer = {
    let schema = Schema([
      UniqueItem.self,
    ])
    let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)

    do {
      return try ModelContainer(for: schema, configurations: [modelConfiguration])
    } catch {
      fatalError("Could not create ModelContainer: \(error)")
    }
  }()

  @Test("Test unique.")
  @MainActor func upsertAndModify() async throws {
    let ctx = sharedModelContainer.mainContext
    try ctx.delete(model: UniqueItem.self)
    let item = UniqueItem(title: "Item \(1)", no: 0)
    ctx.insert(item)

    let allFD = FetchDescriptor<UniqueItem>()
    let count = try ctx.fetchCount(allFD)
    #expect(count == 1)

    let updatedItem = UniqueItem(title: "Item \(1)", no: 0)
    updatedItem.changed = true
    ctx.insert(updatedItem)

    // we should still have only 1 item because of the unique constraint
    let allCount = try ctx.fetchCount(allFD)
    #expect(allCount == 1)
  }
}

This is still an issue in the RCs for iOS 18 & Xcode 16

I am experiencing a similar issue. The insert of a new record with the same values in the #unique fields as an existing record fails. Which would make #Unique more or less useless, if I have to check for existence of the same combination of values before anyway.

Is SwiftData's #Unique currently broken or am I missing something?
 
 
Q