@Attribute 'unique' and complex keys

The 'unique' attribute is a really nice feature, BUT. In some of my apps, the unique identifier for an object is a combination of multiple attributes. (Example: a book title is not unique, but a combination of book title and author list is.)

How do I model this with SwiftData? I cannot use @Attribute(.unique) on either the title OR the author list, but I want SwiftData to provide the same "insert or update" logic.

Is this possible?

Replies

I have a similar question also, for now I would create and UUID instead of complex key, e.g.:

@Attribute(.unique) var identifier: UUID

I tested define @Attribute(.unique) multiple times and seems not a correct solution:

@Model final class Book {
    @Attribute(.unique)
    var title: String
    @Attribute(.unique)
    var author: String
}

I tried to insert books have some wried result:

container.mainContext.insert(BooK(title: "book 1", author: "author 1"))
try? container.mainContext.save()

// 1 book inserted

container.mainContext.insert(BooK(title: "book 1", author: "author 1"))
try? container.mainContext.save()

// 1 book inserted as expected

container.mainContext.insert(BooK(title: "book 2", author: "author 1"))
try? container.mainContext.save()

// "book 2" replace "book 1", and 1 book is left.

My workaround: create our own unique key with title and author:

@Model final class Book {
    @Attribute(.unique)
    var titleAndAuthor: String    
    
    var title: String
    var author: String

    init(title: String, author: String) {
        self.title = title
        self.author = author
        titleAndAuthor = self.title + self.author
    }
}