Crash when sorting SwiftData Query with a SortDescriptor made from a KeyPath with an optional relationship in the chain

271 views Asked by At

I have the following models:

@Model
class Game {
    var name: String
    var firstReleasedOn: Date?

    @Relationship(deleteRule: .cascade, inverse: \QueueEntry.game)
    var queueEntry: QueueEntry?

    init(
        name: String,
        firstReleasedOn: Date?
    ) {
        self.name = name
        self.firstReleasedOn = firstReleasedOn
    }
}
@Model
public class QueueEntry {
    var game: Game?
    var createdOn: Date
    var order: Int

    init(order: Int) {
        self.createdOn = .now
        self.order = order
    }
}

I want to populate a List with all entries sorted by their game's release date, so I have the following:

struct QueueView: View {
    @Query(sort: [SortDescriptor(\QueueEntry.game?.firstReleasedOn)])
    private var entries: [LocalData.QueueEntry]
    
    var body: some View {
        List(entries) { entry in
            Text(entry.game.name ?? "")
        }
    }
}

Running the above code in Debug is totally fine. Running in Release, however, throws the following error:

SwiftData/DataUtilities.swift:65: Fatal error: Couldn't find \QueueEntry.<computed 0x00000001049cd3e0 (Optional)>?.<computed 0x00000001049cd440 (Optional)> on QueueEntry with fields [SwiftData.Schema.PropertyMetadata(name: "game", keypath: \QueueEntry.<computed 0x00000001049e3814 (Optional)>, defaultValue: nil, metadata: nil), SwiftData.Schema.PropertyMetadata(name: "createdOn", keypath: \QueueEntry.<computed 0x00000001049e40e8 (Date)>, defaultValue: nil, metadata: nil), SwiftData.Schema.PropertyMetadata(name: "order", keypath: \QueueEntry.<computed 0x00000001049e49ac (Int)>, defaultValue: nil, metadata: nil)]

QueueEntry.game needs to be optional since making it non-optional and trying to create the relationship in the init results in an NSInvalidArgumentException, reasoning explained here by Joakim Danielson.

Is this just a bug/issue with SwiftData that needs to be addressed by Apple? Is there some other workaround I can implement that maintains the integrity of the relatioship between Game and QueueEntry?

0

There are 0 answers