User95797654974
User95797654974

Reputation: 624

FetchReqeust of many items with predicate causing stuttering swiftui animations

I have about 5000 bus stop entities stored in core data. I fetch them with a predicate that is within a certain delta of latitude and longitude to get the bus stops near to the user's location and display them on the map. But I am getting extremely bad performance and very high CPU usage even after filtering with NSPredicate

As I continuously dismiss and bring up the SwiftUI List containing the nearby bus stops, the animation stutter worsens.

Note: I ran this method inside the task modifier when the map appears. I did try with both main view context and a background view context and both caused severe stuttering issues in my app's animations

@Observable
class NearbyBusStopsViewModel {
    static let shared = NearbyBusStopsViewModel()
    var nearbyBusStops = [BusStop]()
    let request = BusStop.fetchRequest()
    let viewContext = DataProvider.shared.container.newBackgroundContext()

   //location is the user location passed
    func fetchNearbyBusStops(for location: CLLocationCoordinate2D) {
        let latitudeDelta: CLLocationDegrees = 0.003
        let longitudeDelta: CLLocationDegrees = 0.003
        
        let minLatitude = location.latitude - latitudeDelta
        let maxLatitude = location.latitude + latitudeDelta
        let minLongitude = location.longitude - longitudeDelta
        let maxLongitude = location.longitude + longitudeDelta
        
        // Create predicates for latitude and longitude boundaries
        let latitudePredicate = NSPredicate(format: "latitude BETWEEN {%@, %@}", NSNumber(value: minLatitude), NSNumber(value: maxLatitude))
        let longitudePredicate = NSPredicate(format: "longitude BETWEEN {%@, %@}", NSNumber(value: minLongitude), NSNumber(value: maxLongitude))
        
        viewContext.perform { [weak self] in
            guard let self = self else { return }
            // Combine the predicates using NSCompoundPredicate
            let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [latitudePredicate, longitudePredicate])
            request.predicate = compoundPredicate
            
            let busStops = try? viewContext.fetch(request)
            
            if let busStops {
                DispatchQueue.main.async {
                    self.nearbyBusStops = filteredBusStops
                }
            }
        }
    }
}

Upvotes: 0

Views: 113

Answers (0)

Related Questions