You're all set!

To start developing, please head over to our developer documentation.

Activate the Google Maps SDK for iOS

To get you started we'll guide you through the Google Developers Console to do a few things first:

  1. Create or choose a project
  2. Activate the Google Maps SDK for iOS
  3. Create appropriate keys
Continue

Select Current Place and Show Details on a Map

This tutorial shows you how to build an iOS app to:

  • Get the current device location.
  • Get a list of places where the device is likely to be located.
  • Prompt the user for the best place match.
  • Show a marker on the map.

Follow this tutorial to build an iOS app using the Places API for iOS, the Maps SDK for iOS, and the Apple Core Location framework.

Get the code

Clone or download the Google Maps iOS samples repository from GitHub.

Set up your development project

Follow these steps to install the Google Places API for iOS and the Google Maps SDK for iOS:

  1. Download and install Xcode.
  2. If you don't already have the CocoaPods tool, install it on macOS by running the following command from the terminal:
    sudo gem install cocoapods
  3. Clone or download the Google Maps iOS Tutorials repository.
  4. Navigate to the current-place-on-map directory.
  5. Run the pod install command. This installs the APIs specified in the Podfile, along with any dependencies they may have.
  6. Open current-place-on-map.xcworkspace in Xcode.

For detailed installation instructions, see Getting Started (Maps), and Getting Started (Places).

Get an API key and enable the necessary APIs

To complete this tutorial, you need a Google API key that's authorized to use the Google Maps SDK for iOS and the Google Places API for iOS. Click the button below to get a key and activate the APIs.

Get a Key

For more details, see Get an API key (Maps) , and Get an API key (Places).

Add the API key to your application

Add your API key to your AppDelegate.swift as follows:

  1. Add the following import statements:
    import GooglePlaces
    import GoogleMaps
  2. Add the following to your application(_:didFinishLaunchingWithOptions:) method, replacing YOUR_API_KEY with your API key:
    GMSPlacesClient.provideAPIKey("YOUR_API_KEY")
    GMSServices.provideAPIKey("YOUR_API_KEY")

Build and run your app

  1. Connect an iOS device to your computer, or select a simulator from the Xcode scheme pop-up menu.
  2. If you're using a device, make sure that location services are enabled. If you're using a simulator, select a location from the Debug/Location menu.
  3. In Xcode, click the Product/Run menu option (or the play button icon).

Xcode builds the app, and then runs the app on the device or on the simulator.

You should see a map with a number of markers centered around your current location, similar to the image on this page.

Troubleshooting:

  • If you don't see a map, check that you've obtained an API key and added it to the app, as described above. Check Xcode's debugging console for error messages about the API key.
  • The map will not display properly if the permissions request for location services is declined.
    • If you're using a device, go to Settings/General/Privacy/Location Services, and re-enable location services.
    • If you're using a simulator, go to Simulator/Reset Content and Settings...
    The next time the app is run, be sure to accept the location services prompt.
  • Ensure that you have a good WiFi or GPS connection.
  • If the app launches but no map is displayed, make sure that you have updated the Info.plist for your project with the appropriate location permissions. For more information about permissions handling, see the guide to requesting location permission in your app below.
  • Use the Xcode debugging tools to view logs and debug the app.

Understand the code

This part of the tutorial explains the most significant parts of the current-place-on-map app, to help you understand how to build a similar app.

The current-place-on-map app features two view controllers: One to display a map showing the user's currently selected place, and one to present the user with a list of likely places to choose from. Note that each view controller has the same variables for tracking the list of likely places (likelyPlaces), and for indicating the user's selection (selectedPlace). Navigation between views is accomplished by using segues.

Request location permission

Your app must prompt the user for consent to use location services. To do this, include the NSLocationAlwaysUsageDescription key in the Info.plist file for the app, and set the value of each key to a string that describes how the app intends to use location data.

Set up the location manager

Use CLLocationManager to find the device's current location and to request regular updates when the device moves to a new location. This tutorial provides the code you need to get the device's location. For more details, see the guide to Getting the User's Location in the Apple Developer Documentation.

  1. Declare the location manager, current location, map view, places client, and default zoom level at the class level.
  2. var locationManager = CLLocationManager()
    var currentLocation: CLLocation?
    var mapView: GMSMapView!
    var placesClient: GMSPlacesClient!
    var zoomLevel: Float = 15.0
    
    
  3. Initialize the location manager and GMSPlacesClient in viewDidLoad().
  4. locationManager = CLLocationManager()
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestAlwaysAuthorization()
    locationManager.distanceFilter = 50
    locationManager.startUpdatingLocation()
    locationManager.delegate = self
    
    placesClient = GMSPlacesClient.shared()
    
    
  5. Declare variables to hold the list of likely places, and the user's selected place.
  6. // An array to hold the list of likely places.
    var likelyPlaces: [GMSPlace] = []
    
    // The currently selected place.
    var selectedPlace: GMSPlace?
    
    
  7. Add delegates to handle events for the location manager, using an extension clause.
  8. extension MapViewController: CLLocationManagerDelegate {
    
      // Handle incoming location events.
      func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location: CLLocation = locations.last!
        print("Location: \(location)")
    
        let camera = GMSCameraPosition.camera(withLatitude: location.coordinate.latitude,
                                              longitude: location.coordinate.longitude,
                                              zoom: zoomLevel)
    
        if mapView.isHidden {
          mapView.isHidden = false
          mapView.camera = camera
        } else {
          mapView.animate(to: camera)
        }
    
        listLikelyPlaces()
      }
    
      // Handle authorization for the location manager.
      func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        switch status {
        case .restricted:
          print("Location access was restricted.")
        case .denied:
          print("User denied access to location.")
          // Display the map using the default location.
          mapView.isHidden = false
        case .notDetermined:
          print("Location status not determined.")
        case .authorizedAlways: fallthrough
        case .authorizedWhenInUse:
          print("Location status is OK.")
        }
      }
    
      // Handle location manager errors.
      func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        locationManager.stopUpdatingLocation()
        print("Error: \(error)")
      }
    }
    
    

Add a map

  • Create a map and add it to the view in viewDidLoad() in the main view controller. The map stays hidden until a location update is received (location updates are handled in the CLLocationManagerDelegate extension).
  • let camera = GMSCameraPosition.camera(withLatitude: defaultLocation.coordinate.latitude,
                                          longitude: defaultLocation.coordinate.longitude,
                                          zoom: zoomLevel)
    mapView = GMSMapView.map(withFrame: view.bounds, camera: camera)
    mapView.settings.myLocationButton = true
    mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    //mapView.isMyLocationEnabled = true
    
    // Add the map to the view, hide it until we've got a location update.
    view.addSubview(mapView)
    mapView.isHidden = true
    
    

Prompt the user to select their current place

Use the Places API for iOS to get the top five place likelihoods based on the user's current location, and present the list in a UITableView. When the user selects a place, add a marker to the map.

  1. Get a list of likely places to populate a UITableView, from which the user can select the place where they are currently located.
  2. // Populate the array with the list of likely places.
    func listLikelyPlaces() {
      // Clean up from previous sessions.
      likelyPlaces.removeAll()
    
      placesClient.currentPlace(callback: { (placeLikelihoods, error) -> Void in
        if let error = error {
          // TODO: Handle the error.
          print("Current Place error: \(error.localizedDescription)")
          return
        }
    
        // Get likely places and add to the list.
        if let likelihoodList = placeLikelihoods {
          for likelihood in likelihoodList.likelihoods {
            let place = likelihood.place
            self.likelyPlaces.append(place)
          }
        }
      })
    }
    
    
  3. Open a new view to present likely places to the user. When the user taps "Get Place", we segue to a new view, and show the user a list of possible places to choose from. The prepare function updates PlacesViewController with the list of current likely places, and is automatically called when a segue is performed.
  4. // Prepare the segue.
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      if segue.identifier == "segueToSelect" {
        if let nextViewController = segue.destination as? PlacesViewController {
          nextViewController.likelyPlaces = likelyPlaces
        }
      }
    }
    
    
  5. In PlacesViewController, fill the table using the list of most likely places, using the UITableViewDataSource delegate extension.
  6. // Populate the table with the list of most likely places.
    extension PlacesViewController: UITableViewDataSource {
      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return likelyPlaces.count
      }
    
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath)
        let collectionItem = likelyPlaces[indexPath.row]
    
        cell.textLabel?.text = collectionItem.name
    
        return cell
      }
    
      // Show only the first five items in the table (scrolling is disabled in IB).
      func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return self.tableView.frame.size.height/5
      }
    
      // Make table rows display at proper height if there are less than 5 items.
      func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        if (section == tableView.numberOfSections - 1) {
          return 1
        }
        return 0
      }
    }
    
    
  7. Handle the user's selection using the UITableViewDelegate delegate extension.
  8. class PlacesViewController: UIViewController {
    ...
      // Pass the selected place to the new view controller.
      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "unwindToMain" {
          if let nextViewController = segue.destination as? MapViewController {
            nextViewController.selectedPlace = selectedPlace
          }
        }
      }
    }
    ...
    // Respond when the user selects a place.
    extension PlacesViewController: UITableViewDelegate {
      func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        selectedPlace = likelyPlaces[indexPath.row]
        performSegue(withIdentifier: "unwindToMain", sender: self)
      }
    }
    
    

Add a marker to the map

  • When the user makes a selection, use an unwind segue to return to the previous view, and add the marker to the map. The unwindToMain IBAction is called automatically upon returning to the main view controller.
  • // Update the map once the user has made their selection.
    @IBAction func unwindToMain(segue: UIStoryboardSegue) {
      // Clear the map.
      mapView.clear()
    
      // Add a marker to the map.
      if selectedPlace != nil {
        let marker = GMSMarker(position: (self.selectedPlace?.coordinate)!)
        marker.title = selectedPlace?.name
        marker.snippet = selectedPlace?.formattedAddress
        marker.map = mapView
      }
    
      listLikelyPlaces()
    }
    
    

Congratulations! You've built an iOS app that lets the user choose their current place, and shows the result on a Google map. In the course of doing this, you've learned how to use the Places API for iOS, the Maps SDK for iOS, and the Apple Core Location framework.

Next steps

Learn about the place picker, a UI widget that displays an interactive map and a list of nearby places for the user to choose from.

Send feedback about...

Google Maps SDK for iOS
Google Maps SDK for iOS
Need help? Visit our support page.