Implementing Reverse Geocoding (Address from Coordinates) in Mobile Apps
Reverse geocoding — converting a pair (latitude, longitude) into a readable postal address — often becomes a headache on mobile platforms due to rate limits and incomplete databases. The task looks trivial, but in practice reveals pitfalls: standard solutions fail outside cities, under bulk requests, and in offline mode. We break down where typical approaches break and how to build a reliable pipeline.
Why Standard Reverse Geocoding Solutions Fail
On iOS the standard path is CLGeocoder.reverseGeocodeLocation(_:completionHandler:) (see Apple CLGeocoder documentation). Problem: one request per second, a hard rate limit from Apple. To show addresses for 20 points on a map simultaneously, the queue stretches to 15–20 seconds. On Android Geocoder.getFromLocation() before API 33 executes synchronously and throws IOException when offline. Since API 33, GeocodeListener exists, but devices on Android 12 and below don't support it — you must maintain two code paths.
Result quality depends on the provider's database. Apple uses TomTom and HERE, Google uses its own. Outside major cities, addresses may return as "Unnamed Road" only at the district level. Data quality drops by up to 40% in rural areas. In contrast, Google Maps Geocoding API provides 90% accuracy even in remote areas.
How to Avoid Rate Limits and Get Accurate Addresses in Reverse Geocoding
For most projects we use Google Maps Geocoding API — uniform result on iOS and Android, more accurate addresses in CIS, predictable format. It is 5x more accurate than CLGeocoder in non-urban zones. For Russian cases we add DaData as a second provider: it knows industrial zones and building numbers that Google returns as undefined.
| Provider | Rate limit | Accuracy in CIS | Offline mode | Cost |
|---|---|---|---|---|
| CLGeocoder (iOS) | 1 req/s | Medium | No | Free |
| Geocoder (Android) | synchronous before API 33 | Medium | No | Free |
| Google Maps Geocoding API | 50,000 req/day free | High | Requires caching | Paid |
| DaData | 10,000 req/day free | Very high (Russia) | Requires caching | Paid |
Stack and Configuration
On iOS SDK: GMSGeocoder.reverseGeocodeCoordinate(_:completionHandler:) from the GoogleMaps package. Returns GMSReverseGeocodeResponse with an array of GMSAddress. We take the first, parse thoroughfare, subThoroughfare, locality, administrativeArea, postalCode. See Google Maps Geocoding API docs.
On Android: Retrofit client to maps.googleapis.com/maps/api/geocode/json?latlng=…&language=ru&key=…. We parse address_components by types: street_number, route, locality, administrative_area_level_1. For offline scenarios we additionally cache the last known address in Room tied to coordinates (50-meter matching radius). Caching reduces API calls by 80% and improves latency by 60%.
In Flutter — the geocoding package for the platform geocoder and google_maps_flutter plus direct http requests to the Geocoding API. Important: geocoding on Android under the hood uses the same Geocoder.getFromLocation(), so it cannot be called from the main isolate.
Address Format for Specific Markets
If the app works in Russia — add parameters language=ru®ion=RU and manually sort address_components: city, street, building. Google returns components from large to small, while in Russia the convention is small to large. For projects with DaData we integrate suggestions/api/4_1/rs/geolocate/address as a second provider: it works better with non-standard addresses inside industrial zones. (See DaData geolocation API.)
When to Choose Offline Cache?
Address caching is critical for navigation, delivery, and field work. We store the last known address in a local database (Room/CoreData) tied to coordinates. When offline, the app returns the cache; when connectivity returns, it updates data asynchronously. This fits scenarios where addresses are frequently requested in the same area.
Checklist for Reverse Geocoding Integration
- Determine target markets (Russia/CIS/global) and load (batch/single).
- Choose provider: Google Maps Geocoding API for cross-platform, DaData for Russia.
- Implement a service layer with caching and multi-provider fallback.
- Configure API keys and rate limits.
- Test on edge coordinates (middle of ocean, industrial zones, rural areas).
- Integrate into UI with loading and error states.
What's Included in Our Work
- Requirements audit: online/offline, batch/single, target markets.
- Provider selection and API key setup.
- Service layer implementation with caching (Room/CoreData).
- Testing on edge coordinates: middle of ocean, rural areas, industrial zones.
- UI integration with proper loading and error states.
- Documentation and training for your team.
- Post-launch support for 30 days.
Timelines and Cost
Implementation time: from one day for a basic case (single provider, online) to three to four days for a comprehensive solution with offline cache, multi-provider, and multi-market support. Cost: basic integration starts at $500, comprehensive solution $2000–$3000. We offer flexible conditions and a free audit of your current project.
Our team has over 5 years of mobile development experience; we have implemented geocoding for 30+ projects — from navigation maps to delivery services. We guarantee stable operation even under high loads.
Ready to discuss your project? Contact us — we will assess the task and propose the optimal turnkey solution. For a consultation, fill out the form on our website.







