I'm trying to implement an autocomplete search on Google Maps that will show the location that the user selects on the map with a marker.

Search works fine. The problem is as follows. When I select a location from the search results, I get a GMSPlace object that has the correct name as the selected value, correct place ID (confirmed using this link), but incorrect coordinates (-180.0,-180.0, or the kCLLocationCoordinate2DInvalid constant). I tested this on multiple locations.

Most of this code was borrowed from documentation for the Places API.

import UIKit
import GoogleMaps
import GooglePlaces

class ViewController: UIViewController, UISearchBarDelegate {

    @IBOutlet weak var mapContainer: UIView!
    var mapView: GMSMapView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.mapView = GMSMapView(frame: self.mapContainer.frame)
        self.view.addSubview(self.mapView)
    }

    // Code from https://developers.google.com/places/ios-sdk/autocomplete#add_an_autocomplete_ui_control
    @IBAction func searchByAddress(_ sender: Any) {
        // Present the Autocomplete view controller when the button is pressed.
        let autocompleteController = GMSAutocompleteViewController()
        autocompleteController.delegate = self

        // Specify the place data types to return.
        let fields: GMSPlaceField = GMSPlaceField(rawValue: UInt(GMSPlaceField.name.rawValue) |
            UInt(GMSPlaceField.placeID.rawValue))!
        autocompleteController.placeFields = fields

        // Display the autocomplete view controller.
        present(autocompleteController, animated: true, completion: nil)
    }
}

extension ViewController: GMSAutocompleteViewControllerDelegate {

    // Handle the user's selection.
    func viewController(_ viewController: GMSAutocompleteViewController, didAutocompleteWith place: GMSPlace) {
        let position: CLLocationCoordinate2D = place.coordinate

        let camera = GMSCameraPosition.camera(withLatitude: position.latitude, longitude: position.longitude, zoom: 10)
        let newMapView = GMSMapView.map(withFrame: self.mapContainer.frame, camera: camera)
        self.mapView = newMapView
        self.view.addSubview(newMapView)

        let marker = GMSMarker()
        marker.position = position
        marker.title = place.name
        marker.map = self.mapView

        viewController.dismiss(animated: true, completion: nil)
    }

    func viewController(_ viewController: GMSAutocompleteViewController, didFailAutocompleteWithError error: Error) {
        // TODO: handle the error.
        print("Error: ", error.localizedDescription)
    }

    // User canceled the operation.
    func wasCancelled(_ viewController: GMSAutocompleteViewController) {
        viewController.dismiss(animated: true, completion: nil)
    }

    // Turn the network activity indicator on and off again.
    func didRequestAutocompletePredictions(_ viewController: GMSAutocompleteViewController) {
        UIApplication.shared.isNetworkActivityIndicatorVisible = true
    }

    func didUpdateAutocompletePredictions(_ viewController: GMSAutocompleteViewController) {
        UIApplication.shared.isNetworkActivityIndicatorVisible = false
    }

}

Any help would be appreciated!

1 Answers

0
preyes On Best Solutions

I was facing the same issue and went through the Place SDK documentation which says clearly that we should define before hand to the GMSPlaceField of what details do we need exactly and if you had followed the doc completely, it would be resulting only in the name and placeId being populated. So while instantiating your GMSAutoCompleteViewController define in the following way.

**let fields: GMSPlaceField = GMSPlaceField(rawValue:UInt(GMSPlaceField.name.rawValue) |
            UInt(GMSPlaceField.placeID.rawValue) |
            UInt(GMSPlaceField.coordinate.rawValue) |
            GMSPlaceField.addressComponents.rawValue |
            GMSPlaceField.formattedAddress.rawValue)!
autocompleteController.placeFields = fields**