SwiftUI MapKit makeUIView Repeatedly Called Every Other Time

I have a SwiftUI app that includes a map with annotations and an overlay of polylines on highways. I use Core Data to store Waypoint structs to configure the polylines. Multiple Waypoints make a Trip.

The app is the basic Master/Detail style with a list of trips and a DetailView that displays the map with the overlay. As a part of that process I calculate the time and distance for each segment (between Waypoints). All of this works as expected with one really strange problem.

When I start the app, the first Trip is displayed correctly with the correct time and distance. However, when clicking on a second Trip the makeUIView function of the UIViewRepresentable is called multiple times - even more strangely, five times. That obviously wastes internet resources and it makes the time and distance incorrect. Now if that is not strange enough, when clicking on a third Trip, the information is correct. In fact, every other Trip is correct - it does not matter which is first, every other is correct with the intervening ones all incorrect. My first thought was that I had some strange toggle somewhere, but I do not. I cannot find anything that should require the makeUIView to be called five times and certainly not every other time.

I have attached the

code for the DetailView:

Just as an aside - I published this app to the App Store some time ago (and several versions of iOS and Xcode ago) and I believe the app behaved as expected at that time.

Any guidance would be appreciated. Xcode 12.5 iOS 14.5

Replies

Given your description of how the issue of multiple calls to makeUIView seems to occur at the time of selecting a trip, the code of the DetailMapView does not seem sufficient to understand the full context.

I would recommend that you gradually try to distill your code into the smallest possible runnable project where the issue still reproduces.

This could help you isolate what piece of code is actually causing this behavior. If you still can't find any explanation for it in its simplest form, please file a report via Feedback Assistant (https://feedbackassistant.apple.com/) and make sure you include the runnable project.

  • It gets even more strange. I removed the map functionality and just made a UIViewRepresentrable with a UILabel on it. I included a counter to verify the number of times makeUIView is called. The result was the same – multiple calls to makeUIView every other tap on the list.

    I then turned to the data source for the list – a Core Data property. I use this wrapper:

    @FetchRequest(fetchRequest: Trip.getAllTrips()) var allTrips: FetchedResults<Trip>

    Believe it or not, if I comment out the @FetchRequest and replace the data for the list with the following, the problem is fixed. This, of course, introduces other issues with .onDelete and more but, to me, it identifies the problem as that wrapper.

    var allTrips: [Trip] { var answer: [Trip] = [] let request: NSFetchRequest<Trip> = Trip.fetchRequest() as! NSFetchRequest<Trip> let sortDescriptor = NSSortDescriptor(key: "name", ascending: true) request.sortDescriptors = [sortDescriptor] do { let results = try managedObjectContext.fetch(request) answer = results } catch { print(error) } return answer }

    I THINK that my issue is resolved with Xcode 13 and iOS 15 but I cannot test with my app due to another bug in the beta dealing with something about texture libraries. That seems to be a known bug.

Add a Comment

It gets even more strange. I removed the map functionality and just made a UIViewRepresentrable with a UILabel on it. I included a counter to verify the number of times makeUIView is called. The result was the same – multiple calls to makeUIView every other tap on the list.

I then turned to the data source for the list – a Core Data property. I use this wrapper:

@FetchRequest(fetchRequest: Trip.getAllTrips()) var allTrips: FetchedResults<Trip>

Believe it or not, if I comment out the @FetchRequest and replace the data for the list with the following, the problem is fixed. This, of course, introduces other issues with .onDelete and more but, to me, it identifies the problem as that wrapper.

var allTrips: [Trip] {
    
    var answer: [Trip] = []
    let request: NSFetchRequest<Trip> = Trip.fetchRequest() as! NSFetchRequest<Trip>
    
    let sortDescriptor = NSSortDescriptor(key: "name", ascending: true)
    request.sortDescriptors = [sortDescriptor]

    do {
        let results = try managedObjectContext.fetch(request)
        answer = results
    } catch {
        print(error)
    }
    return answer
}

I THINK that my issue is resolved with Xcode 13 and iOS 15 but I cannot test with my app due to another bug in the beta dealing with something about texture libraries. That seems to be a known bug.