I have two SwiftData models like below:

@Model
final class SDStock {
   init() {}

   var id = UUID()

   var title = "abc"
   var code = "123456"

   @Relationship(deleteRule: .cascade, inverse: \SDValue.stock)
   var historyValueList: [SDValue]? = []
}

@Model
final class SDValue {
   init() {}

   var id = UUID()

   var stock: SDStock?
   var date = Date.now
   var value = 0.0
}

As time grows, the app will have hundreds of stocks, and each stock will have thousands of values for historyValueList. The app should show the latest value for each stock, because SwiftData stores array as Set, so historyValueList should be sorted as per date, which caused serious performance problem when the user tap or navigate to other views.

So, is there any way to improve SwiftData sorting performance for its Set variables?

Thanks in advance!

9 Replies 9

Use Query instead, I have a personal general rule to never use Relationship arrays because of the lack of listening, sorting, filtering, etc.

Make sure your relationship has a parent field and query the objects instead.

What does the time profiler say was causing the performance issues. Find out why you are getting a CPU hit. Are you sorting on each access with a synthetic var or are you caching your sorted set somewhere.

Maybe you need to rethink the design and differentiate between the current value and historic values to avoid having to hit the relationship property every time you need the latest price.

@Iorem ipsum, thanks! If you do not use relationship arrays, how do you design SwiftData models? Like this question, historyValueList should be a series of values, it seems there's no other way to store many values in SwiftData.

@Warren Burton, Thanks! Yes, I'm sure it's a sorting performance problem. Each time the user tap the app, there're tens to hundreds of calculations are working depending on the latest sorted value. I have tried to use async/await, the result is not that good, still feels stuck.

@Joakim Danielson, Thanks! Creating another variable to represent the latest value is also a good suggestion!

You're not showing how or where you're doing the sorting. Are you sorting in the view or are you using a SortDescriptor in the Query, or else?

@Andrei G. , I'm using SwiftData with UIKit, I think it's noting to do for the view. Is a SortDescriptor possible used for the Model array variable? By now, I only see the case using SortDescriptor to Query on models.

No you can not sort on a to-many relationship (array).

Your Reply

By clicking “Post Your Reply”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.