-1

I don't know how to approach this issue, so I'm looking for some suggestions:

I have an airports list database with over 75K airports on it, and it is very very slow to open it when I use on my view@Query() var airports: [Airport]

So I understand I need to load a shorted list of this array, for each alphabet letter I want to pick 10 airports and add it to a 'shortairports' array in order to display it faster.

my attempt: On the model I have tried to add a static var that should return a FetchDescriptor shorted to be used in my view as @Query(short) var airports: [Airport] but I'm stuck... see below code:

@Model
class Airport {
    @Attribute(.unique) var id: UUID
    var lastPicked : Date
    var icao : String
    
    init(id: UUID, lastPicked: Date, icao: String) {
        self.id = id
        self.lastPicked = lastPicked
        self.icao = icao
    }
    
    static var short: FetchDescriptor<Airport> {
        let alphabet = ["0","1","2","3","4","5", "6", "7", "8", "9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
        let sort = [SortDescriptor(\Airport.icao, order: .forward)]
        
        var shortAirports = FetchDescriptor<Airport>()
        
        alphabet.forEach { letter in
            let predicate = #Predicate<Airport> { input in
               input.icao.prefix(1) == letter // error here //
//The prefix(_:) function is not supported
            }
            var apts = FetchDescriptor(predicate: predicate, sortBy: sort)
            apts.fetchLimit = 10
            // now i have 10 airports i wanted to add in an array of [Airports]
//            shortAirports.append ?? /// <--->
        }
        
        return shortAirports
    }

   
}


Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
Damiano Miazzi
  • 1,514
  • 1
  • 16
  • 38
  • Why don't you paginate the data instead? Load the first 20 items and so on. – Timmy Aug 09 '23 at 09:26
  • sorry i don't understand? – Damiano Miazzi Aug 09 '23 at 09:28
  • Load the first 20 airports, check when the last airport has been displayed on screen and load the next 20. Make sure that you're using a lazy container like `List`, `LazyVStack`... – Timmy Aug 09 '23 at 09:30
  • This looks like a bad idea and also note that fetchLimit doesn't seem to work, https://stackoverflow.com/questions/76699005/how-to-limit-the-number-of-items-in-a-fetch-request – Joakim Danielson Aug 09 '23 at 09:54
  • 1
    It seems, you are still performing the query in the view. If this operations is _actually_ slow (I have my doubts, honestly) then, and only then, you should NOT perform the query in the view. Instead, use a model performing this query asynchronuosly, and set the view into a "loading" state. When the computation finished, publish the state (failure or data) to the view. This approach also works nicely when the query is fast. So, it will be THE solution. – CouchDeveloper Aug 09 '23 at 11:20
  • Then, when rendering a large list of items is slow, and only when _rendering_ is slow, try to find a solution with SwiftUI. This has nothing to do where the data comes from. You can easily mock this scenario with fake data, without CoreData or network. – CouchDeveloper Aug 09 '23 at 11:26
  • have to add: don't confuse `@Model` - which is a SwiftData thing, with a (View) "model" or "View Model". Sorry, for being not clear. – CouchDeveloper Aug 09 '23 at 11:34
  • 1
    Off topic but do you really need 75K airports in your database? Maybe you can improve performance only by doing some work selecting what data should be included in your app? – Joakim Danielson Aug 09 '23 at 12:02

0 Answers0