Implement Address Lookup on Marker Click in an iOS App (Capacitor + Xcode + Google Maps)

1. Overview

When building hybrid mobile applications with Ionic Capacitor for iOS, you can embed Google Maps to offer a native-like map experience. A common use case is performing a reverse geocoding lookup — converting marker coordinates into a readable address when a user taps on a marker.

This tutorial walks you through setting up the Google Maps SDK for iOS, configuring permissions in Xcode, and writing TypeScript logic to geocode marker locations using google.maps.Geocoder().


2. Prerequisites

Before you begin, ensure you have:

  • Xcode 14.2 or later
  • Node.js and npm
  • Capacitor installed (npm install @capacitor/core)
  • A valid Google Maps API Key with these APIs enabled:
    • Maps JavaScript API
    • Geocoding API
    • Maps SDK for iOS

3. Configure Google Maps in Xcode

  1. Install Google Maps SDK for iOS via CocoaPodsIn your iOS project directory (usually ios/App), create or update your Podfile:
    platform :ios, '12.0'
    use_frameworks!
    
    target 'App' do
      pod 'GoogleMaps'
    end
    

    Then run:

    pod install
    
  2. Provide your API keyOpen AppDelegate.swift and import the SDK:
    import GoogleMaps
    

    Add the API key inside application(_:didFinishLaunchingWithOptions:):

    GMSServices.provideAPIKey("YOUR_IOS_API_KEY")
    
  3. Add location permissionsOpen your Info.plist and include these keys:
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>We use your location to show nearby points on the map.</string>
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>This app needs your location to display accurate addresses.</string>
    

4. Load the Google Maps JavaScript API in Capacitor

In your index.html (inside src/), load the Google Maps JS API:

<script async defer
  src="https://maps.googleapis.com/maps/api/js?key=YOUR_WEB_API_KEY&libraries=places">
</script>

💡 Tip: Use a different API key for the JS API and restrict it to your app’s bundle identifier or domain for security.


5. Implement the Marker Click Lookup

Inside your component (for example, home.page.ts), define a getAddress() method that uses the google.maps.Geocoder service:

private getAddress(lat: number, lng: number): Promise<string> {
  return new Promise((resolve, reject) => {
    const geocoder = new google.maps.Geocoder();
    const latlng = new google.maps.LatLng(lat, lng);

    geocoder.geocode({ location: latlng }, (results, status) => {
      if (status === google.maps.GeocoderStatus.OK && results[0]) {
        resolve(results[0].formatted_address);
      } else {
        reject(`Geocoder failed: ${status}`);
      }
    });
  });
}

Then, call it inside your marker click listener:

this.map.setOnMarkerClickListener(async (marker) => {
  try {
    const address = await this.getAddress(marker.latitude, marker.longitude);
    await this.showAlert('Address Found', address);
    console.log('Marker clicked:', marker, address);
  } catch (error) {
    console.error(error);
  }
});

Note: Always use await to ensure the asynchronous geocoding completes before displaying the result.


6. Troubleshooting “Can’t Find Variable: google”

If you see the error ReferenceError: Can't find variable: google, it means the API script hasn’t finished loading before your code ran.

Fix:
Ensure your map logic executes after the Google Maps script has loaded. You can add this to your HTML:

<script async defer
  src="https://maps.googleapis.com/maps/api/js?key=YOUR_WEB_API_KEY&callback=initMap">
</script>

and define:

(window as any).initMap = () => {
  // initialize map and event listeners here
};

7. Testing in iOS Simulator

  1. Build your Capacitor app:
    ionic capacitor build ios
    
  2. Open the Xcode workspace (App.xcworkspace) and run it on a simulator or a real device.
  3. Click on any map marker to verify that the app correctly displays the formatted address.

8. Conclusion

By combining Capacitor, Google Maps SDK for iOS, and Geocoding API, you can build hybrid apps that deliver smooth, native-quality map interactions on iOS. Handling the lookup asynchronously ensures the UI remains responsive, while native integration via Xcode allows full control over permissions and performance.

This article is inspired by real-world challenges we tackle in our projects. If you're looking for expert solutions or need a team to bring your idea to life,

Let's talk!

    Please fill your details, and we will contact you back

      Please fill your details, and we will contact you back