SwiftData Array in random order?

Why is the order of my array random when i use the @Model macro.

class TestModel {
    var name: String?
    var array: [TestModel2]

    init(name: String = "") {
        self.name = name
        array = []
    }
}

class TestModel2 {
    var name: String?

    init(name: String = "") {
        self.name = name
    }
}

This works fine, and all the items in array are in the order I add them.

But if I declare both of them as @Model, like this:

@Model
class TestModel {
    var name: String?
    var array: [TestModel2]

    init(name: String = "") {
        self.name = name
        array = []
    }
}

@Model
class TestModel2 {
    var name: String?

    init(name: String = "") {
        self.name = name
    }
}

The array items are always in a random order. When I reload the view where they are displayed or when I add items to the array the order is randomised.

Is this a beta bug? Or is this intended?

Post not yet marked as solved Up vote post of falconAgony Down vote post of falconAgony
1.1k views

Replies

Same behaviour here on Xcode beta 15.0 beta 8. It drives me crazy.

Indeed a bit crazy…

I also have this problem. My workaround was to add a timestamp or order variable to my TestModel2 equivalent, and then to add a computed property to my TestModel equivalent to return the sorted list when I need it.

@Model
class TestModel {
    var name: String?
    var unsortedArray: [TestModel2]
    var sortedArray: [TestModel2] {
        return array.sorted(by: {$0.order < $1.order})
    }

    init(name: String = "") {
        self.name = name
        array = []
    }
}
@Model
class TestModel2 {
    var name: String?
    var order: Int

    init(name: String = "",order: Int = 0) {
        self.name = name
        self.order = order
    }
}

Also wondering about this. Because in my app the order is important, and I give users the option to reorder the items.

Sorting after the fact with a computed property is fine for display, but this is much more of a headache when trying to persist an ordering change.

Very confused right now. I have the same problem because I want users to be able to reorder elements and this is nowhere in the documentation.

I came up with the most elegant workaround I could and posted it as a small sample app here:

https://github.com/hekuli/swiftdata-test

The gist is that I make the model's array private, and have a corresponding public computed property that always sorts the array when accessed. I also use a Factory pattern for higher-level orchestration to manipulate the models b/c I encountered too many SwiftData crashes if model operations were not performed in exact order it likes.

I'm still not sure if this is the best approach, so I'd love to hear any suggestions on how it could be improved.