MapKit tile requests result in 410

Hi,


There is a problem with MapKit on iOS - map sometimes fails to load, another time it loads partially, displaying plain grid for a tile which failed to load. The problem happens systemwide in every app that uses MapKit, even in Apple Maps app. The problem happens on both iPhones (6+) and iPads (iPad Air, iPad Air 2, iPad Mini) and a range of iOS versions (9.0, 9.0.2, 9.2.1). Furthermore it seems to happen more often when map zoom is high. The problem is very hard to reproduce, because it looks to happen randomly, persists on affected device for some time and suddenly disappears.


I managed to analyse network traffic and found possible reason of this strange behaviour. Network requests associated with missing tiles fail with HTTP status code 410 and empty content:


GET http://gspe19.ls.apple.com/tile.vf?flags=1&style=13&size=2&scale=0&v=11040322&z=15&x=17923&y=10756&sid=SOME_SID_1&accessKey=SOME_ACCESS_KEY_1 <- 410
GET http://gspe19.ls.apple.com/tile.vf?flags=1&style=20&size=2&scale=0&v=11040322&z=15&x=17923&y=10756&sid=SOME_SID_1&accessKey=SOME_ACCESS_KEY_1 <- 410
...

'v' parameter seems to be a map version number and grow with time. It looks that the version number can change after a 'geo_manifest' network call, which happens from time to time:


GET https://gspe35-ssl.ls.apple.com/geo_manifest/dynamic/config?application=geod&application_version=1&country_code=PL&hardware=iPad4,2&os=ios&os_build=13C75&os_version=9.2

After downloading new geo_manifest, version number becomes valid once again and every tile request ends successfully with HTTP status code 200:


GET http://gspe19.ls.apple.com/tile.vf?flags=1&style=13&size=2&scale=0&v=11040529&z=15&x=17923&y=10756&sid=SOME_SID_2&accessKey=SOME_ACCESS_KEY_2 <- 200
GET http://gspe19.ls.apple.com/tile.vf?flags=1&style=20&size=2&scale=0&v=11040529&z=15&x=17923&y=10756&sid=SOME_SID_2&accessKey=SOME_ACCESS_KEY_2 <- 200
...

I used an lldb to confirm, that a stale geo_manifest is the reason of 410 responses. I ran an arbitrary app on device that showed the symptoms using Xcode. Some tiles were missing on a MKMapView, and 410 responses appeared in network traffic. I closed the map, paused execution with lldb, executed a private GeoService framework method that seemed to force geo_manifest update:


(lldb) po [[GEOResourceManifestManager sharedManager] forceUpdate]

After resuming execution, geo_manifest update request appeared in network traffic. After opening map view, successful tile responses appeared and map was fully loaded. Looks like com.apple.geod daemon itself fails to query for new geo_manifest from time to time. Because the problem is so ephemeral, it was impossible to find any com.apple.geod errors in device console logs.


Following questions arise: why do com.apple.geod, GeoServices or MapKit not try to query for new geo_manifest when tile request results in 410 response? Is that a known issue? Does Apple plan to fix this in future iOS versions?


Regards,

Kamil

Replies

The only way it will get fixed is if they know about it 🙂 so make sure to file a bug report. They almost never acknowledge bugs or give any information about a timeline for fixes here in the forums so don't expect any feedback though.


(Excellent work diagnosing the problem!)

Thanks for your suggestion 🙂 rdar://25267344

Hi Kamil,


I just posted a similar error in another topic. In my case map details were missing on my iPhone 6 but were fine on my iPad Air 2 (universal app)


I've just rebooted my iPhone 6 and all is fine now. Very strange.

A couple things to add that I've observed myself. First, you can capture the error by implementing the delegate method mapViewDidFailLoading. While the error strings don't have much of interest, the userInfo property has a dictionary of the failed tile queries under the name SimpleTileRequesterUnderlyingErrors. In my case, I got first 5 failed tile queries, then 25.


Second, I visited Apple Maps to try to localize the problem (Maps worked fine), but returned to my app to see the issue had disappeared.