MapKit super slow loading tiles stored on device

Loading tile overlays is slow even when the raster data is locally available on the device running iOS 18.2 and built with Xcode 16.2.

In this video (https://3dtopo.com/superSlowTileLoading.mov) it takes 38 seconds to load tiles readily available on the device. Then, the whole screen flashes when tiles that are already drawn are redrawn, making for a very poor user experience. 38 seconds to load a dozen or so small images (512x512) stored locally on the device is simply unacceptable. I can't release a product like this that I've spent the last 1.5 years building and many years developing the maps themselves. This severe issue is new since I committed to basing my app on MapKit.

Note that this issue does not occur with Apple's base map tiles.

I created a Feedback Assitant case, FB16110803, for this issue.

For the video, I disabled loading any tiles from the network and disabled loading any other data, such as polylines. Essentially all I am doing is loading the tiles stored on the device and returning them, such as:

public func loadTile(at path: MKTileOverlayPath, result: @escaping (Data?, Error?) -> Void) {
        fetchData(forKey: key,
    failure: {error in result(nil, error)},
    success: {data in result(data, nil)})
}

open func fetchData(forKey key: String, failure fail: ((Error?) -> ())? = nil, success succeed: @escaping (Data) -> ()) {
    let path = self.path(forKey: key)
    do {
        let data = try Data(
               contentsOf: URL(fileURLWithPath: path),
               options: Data.ReadingOptions())
        succeed(data)
        self.updateDiskAccessDate(atPath: path)
    } catch {
        if let block = fail {
            block(error)
        }
    }
}

I tried pausing the runtime when waiting the ~38 seconds shows it is running an internal Metal command on the Main Thread

Even though I simplified the code I was using for testing purposes the sample code I posted, I created an absolute bare bones MKTileOverlay and the same issue is not occurring.

I was going to delete this post until I can find out exactly what is causing the issue, but I don't see how.

Do you have a test project somewhere that I could look at? I don't see one attached to FB16110803. Further, we have a sample code project that you can download to compare your implementation choices. That project uses both local tiles and server tiles. Are you able to reproduce the same performance bottlenecks via our published sample project?

— Ed Ford,  DTS Engineer

Thanks, Ed. As I mentioned, I don't know how to recreate it using a bare-bones implementation like the sample code. I am using a framework called MapCache that used to work before sometime around iOS 18, but for the video I shot, I forced it to use the simple code I posted. If I can figure out what is causing it, I will post a sample project.

I encountered this issue while trying to work around the reproducible issues FB16009863 and FB14553276. But when I use simple code that doesn't cause the issue reported above, it causes the reproducible issue FB13989005 - which causes the entire screen to flicker every time a zoom level is changed with my very simplified code (provided with that FB). Which is based on Apple's sample code. Sadly it makes zooming a rather jarring experience. The only thing I can do to minimize it is to disable the .canReplaceContent property, but then it downloads and renders Apple's maps which will be completely covered and so is a waste of bandwidth and processing/energy consumption.

MapKit super slow loading tiles stored on device
 
 
Q