Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftData IOS 17 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.

This behaviour can also be seen in the sample code here. When adding bucket list items to a trip, the items are always displayed in a random order.

Is this a beta bug? Or is this intended?

like image 323
Florian Liegl Avatar asked Nov 29 '25 23:11

Florian Liegl


2 Answers

I had the same issue. Like the others said in the comments, I had to add a timestamp to my SwiftData model and sort by that. It must be a bug or something.

@Model
final class YourObject {
    let timestamp: Date
    // Other variables
}

And then in your view, you can do something like this:

@Query private var yourObjects: [YourObject]

List {
    ForEach(yourObjects.sorted(by: {$0.timestamp < $1.timestamp})) { object in 
        // Other code here
    }
}
like image 122
Joseph Kessler Avatar answered Dec 02 '25 15:12

Joseph Kessler


To elaborate on the timestamp sorting answer above (Also I think I might have just also replied to you on the Apple Developer Forums), you can add both a timestamp/order variable to your TestModel2 AND a computed property to your TestModel to return your sorted array when you need it instead of needing to manually sort it every time you want to use it in the UI.

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

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

    init(name: String = "",order: Int = 0) {
        self.name = name
        self.order = order
    }
}
like image 26
jamesyoungSOusername Avatar answered Dec 02 '25 15:12

jamesyoungSOusername



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!