MapKit tile requests result in 410
| Originator: | kamil.borzym | ||
| Number: | rdar://25267344 | Date Originated: | 21-Mar-2016 01:02 PM |
| Status: | Closed | Resolved: | 10-Jul-2016 05:54 PM |
| Product: | iOS SDK | Product Version: | 9.0 |
| Classification: | Reproducible: | No |
Summary: 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? Steps to Reproduce: Unknown, please read description. Expected Results: MapKit should try to get new geo_manifest when tile request results in 410, then retry to get tile. Actual Results: MapKit displays empty map tile when a tile request result is 200. Version: iOS 9.0, iOS 9.0.2, iOS 9.2.1 Notes: Problem described here: https://forums.developer.apple.com/thread/43077 Configuration: iPhone 6+, iPad Air, iPad Air 2, iPad Mini Attachments:
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!
Kamil Borzym 10-Jul-2016 05:54 PM
Tested on iOS 10 beta 2 with a mitmproxy using a script that changes every tile request status code to 410.
def response(context, flow): if flow.request.path.startswith("/tile.vf"): flow.response.status_code = 410 flow.response.content = b""
After couple of unsuccessful tile requests geod tries to update manifest. The bug is solved. Thanks! This issue has been verified as resolved and can be closed.
Apple Developer Relations 17-Jun-2016 08:15 PM
Please clarify your last update.
Are you still hitting the issue?
Please test with iOS 10 beta and let us know what the behavior is.
https://developer.apple.com/download/
Please let us know whether the issue is resolved for you by updating your bug report.