How can you determine if the map tiles in MapKit have successfully loaded?

We are developers of a golf app designed to assist golfers on the course. A key feature of our app is displaying a map of each hole, and we are currently transitioning to using MapKit and camera functionalities for this purpose. However, we are encountering issues with the downloading of map tiles when using the default satellite imagery.

We have tried several approaches to diagnose the issue:

We have tried several things to diagnose the issue:

  • We implemented the mapViewDidFailLoadingMap delegate method. But it is inconsistent, sometimes triggering offline errors even when map tiles are cached.
  • We implemented, the mapViewDidFinishRenderingMap method, but it always returns false when offline or you won't get the callback. Which doesn't let us know that rendering tiles has failed.

We would appreciate your guidance on the following specific questions:

  1. Does MapKit provide a way to confirm if a map tile has fully loaded?
  2. Is there a method to detect if a portion of the map hasn't loaded or if a tile request has failed?
  3. Can we determine whether a map tile is cached, and if so, how long it will remain cached, similar to Cache-Control HTTP headers?
  4. Is there a way to trigger the preloading of map tiles when we know the user has a good internet connection?

Please see the sample project for steps to reproduce the issue.

Thank you for any assistance!

I appreciate your sample project!

I can't fully reproduce this:

We implemented, the mapViewDidFinishRenderingMap method, but it always returns false when offline or you won't get the callback. Which doesn't let us know that rendering tiles has failed.

When I follow the instructions in your sample ReadMe (using iOS 18.2.1), I get this delegate method returning false for holes that are missing tiles. When I switch to holes 1 and 2, I get true in the fully rendered parameter, though switching between holes 1 and 2 means I don't always get this delegate method.

Though those details seem to diverge from what your experience here is, it doesn't really alter the answers for your specific questions.

  1. Does MapKit provide a way to confirm if a map tile has fully loaded?

At the individual tile level for the system provided map, no. At a macro level, you are informed if all the visible map area is rendered through mapViewDidFinishRenderingMap(_:fullyRendered:) as you have it in your test project. I'm answering about rendering here, but you're asking about loading though, which takes us to question 2.

  1. Is there a method to detect if a portion of the map hasn't loaded or if a tile request has failed?

Similar to number 1, MapKit does not provide API for loading state at the individual tile level for the system provided map. Similar to rendering, mapViewDidFailLoadingMap(_:withError:) reports the macro-level loading state to your app, with the Error parameter providing details about my network state when I enable Airplane Mode for your test project.

  1. Can we determine whether a map tile is cached, and if so, how long it will remain cached, similar to Cache-Control HTTP headers?

There is no API for this.

  1. Is there a way to trigger the preloading of map tiles when we know the user has a good internet connection?

There is no API for this. Apple Maps also has offline maps, but the offline map content isn't available to apps. That'd make a nice enhancement request if you think that would be benefit your needs.

All of the above information is focused on the system-provided map content. One other option you have here for your app's experience is to bring your own map tiles for offline support. MapKit supports rendering your own tiles. Our overlay sample code project has several different scenarios for using your own map tiles, such as fetching from a server, loading from disk locally, and an example that uses some of the networking APIs to help you manage a cache for offline use.

— Ed Ford,  DTS Engineer

Thank you, Ed, for your detailed response. I would appreciate knowing if the tiles have loaded at an individual tile level. I understand that we could only achieve that with our own tiles.

I have found a workaround for offline usage and would like your opinion on it. I discovered that using MKMapSnapshotter while the user is online to precache the tiles works quite well. The only downside is that I have no idea how long the cache will remain valid. Do you have any insight on the time-to-live for a cached tile?

Additionally, I have updated the sample project to include the tile downloader.

How can you determine if the map tiles in MapKit have successfully loaded?
 
 
Q