Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a GMSPlace

I'm using the Google Maps iOS SDK and would like to store recent places (GMSPlace objects) that users search for. I'm running into a problem retrieving those places, as it doesn't seem like GMSPlaces can be instantiated directly.

Is it possible to instantiate a GMSPlace object?

Thanks!

like image 621
Josh Sklar Avatar asked Feb 18 '16 22:02

Josh Sklar


2 Answers

CREATE INSTANCE OF GMS PLACE

Yes you can instantiate a GMS Place Object. The day i looked up on the internet , i ran into your question hoping to find an answer but i didn't find any.

So, i came up with my own solution.Here's how you can create an instance of GMSPlace.

So, my requirement was to store 3 GMS Places in 3 different GMSPlace variables. Here's what i did :

var currentLocation: GMSPlace?
var selectedFromDestination: GMSPlace?
var selectedToDestination: GMSPlace?

Now, currentLocation will store user's current location , selectedFromDestination will store a starting Address Point , whereas selectedToDestination will store a destination Address Point.

Note: Notice that they are all optionals. This is the only i got it to work, since i am still a Noob to Swift.

 //MARK:- FUNCTION FOR GETTING CURRENT LOCATION
 func getCurrentPlace() {

    placesClient.currentPlace(callback: { (placeLikelihoodList, error) -> Void in
        if let error = error {
            print("Pick Place error: \(error.localizedDescription)")
            return
        }

        if let placeLikelihoodList = placeLikelihoodList {
            let place = placeLikelihoodList.likelihoods.first?.place
            if let place = place {
                self.nameLabel.text = place.name + "\(place.coordinate.latitude) , \(place.coordinate.longitude)"
                self.addressLabel.text = place.formattedAddress?.components(separatedBy: ", ")
                    .joined(separator: "\n")

                    //assigning returned GMSPlace place object to currentlocation
                    self.currentLocation = place              

            }
        }
    })
}

Now, in my viewDidLoad() method i called this function getCurrentPlace() which will then fetch the user's current location and store in the currentLocation variable.

Now, you can access this variable anywhere in your ViewController, and access its properties such as

 currentLocation?.formattedAddress
 currentLocation?.coordinate.latitude
 currentLocation?.coordinate.longitude

and so on.

Now, you if you want to store what the user selects as a pickup and destination address for example, read on below :-)

Ohkay, so now you have two textfield on which you need to open up the GSMAutoCompleteViewController(P.S - there are other methods but i preferred to use this as it was easy to implement.)

So you will need a textField Delegate method which will differentiate the two textField based on my strTextFieldType variable and will present the ViewController.

//MARK:- TEXTFIELD DELEGATE
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
    if textField == txtFromDestination
    {
        strTxtFieldType = "FromDestination"

    }
    else if textField == txtToDestination
    {
        strTxtFieldType = "ToDestination"

    }

    let acController = GMSAutocompleteViewController()
    acController.delegate = self
    self.present(acController, animated: true, completion: nil)

    return false
}

I have set the return to false as i don't want the textFields to be editable.

Below is the code for the extension which you need to implement for your ViewController

extension YOUR_VIEWCONTROLLER_NAME: GMSAutocompleteViewControllerDelegate {

func viewController(_ viewController: GMSAutocompleteViewController, didAutocompleteWith place: GMSPlace) {


    print("Place name: \(place.name)")
    print("Place address: \(place.formattedAddress ?? "null")")

    if strTxtFieldType == "FromDestination"
    {
        self.txtFromDestination.text = place.formattedAddress
        self.selectedFromDestination = place

    }
    else
    {
        self.txtToDestination.text = place.formattedAddress
        self.selectedToDestination = place
    }

    print("Place attributions: \(String(describing: place.attributions))")

    self.dismiss(animated: true, completion: nil)

}

 func viewController(_ viewController: GMSAutocompleteViewController, didFailAutocompleteWithError error: Error) {
    // TODO: handle the error.
    //        print("Error: \(error.description)")
    self.dismiss(animated: true, completion: nil)
}

// User canceled the operation.
func wasCancelled(_ viewController: GMSAutocompleteViewController) {
    print("Autocomplete was cancelled.")
    self.dismiss(animated: true, completion: nil)
}
}

There , you are now done. You can access the values stored in selectedFromDestination and selectedToDestination anywhere just like the currentLocation GMSPlace object.

Hope this was helpful; :-D ! Lemme know if it works for you.

like image 183
Zahurafzal Mirza Avatar answered Nov 20 '22 06:11

Zahurafzal Mirza


No, you can't instantiate a GMSPlace object.

like image 1
Infinity James Avatar answered Nov 20 '22 07:11

Infinity James