M. Spencer M. Spencer -4 years ago 130
Swift Question

Display list of places near the user's current location in a UITableView in Xcode using a Google Places API

I'm creating an app in Xcode that will have a popover screen over the map view that allows the user to select from a list of nearby locations based on their current location. I have tried several ways to do this but have not accomplished this. I'm relatively new to coding and the Google Places documentation is a bit too vague for me to work out.

That being said I already have Google Places implemented (downloaded, linked, API key, etc.), so I'm just trying to find the right way to display nearby places in a list view. I am creating this using Swift. Here's what I have so far, so if it's a mess:

import UIKit
import GooglePlaces

class ViewController: UIViewController, UITableViewDataSource {

var placesClient: GMSPlacesClient!

override func viewDidLoad() {
super.viewDidLoad()
self.nearbyPlaces()
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

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

if let placeLikelihoodList = placeLikelihoodList {
for likelihood in placeLikelihoodList.likelihoods {
let place = likelihood.place
}
}
})
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return GMSPlaceLikelihoodList.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = UITableViewCell()
cell.textLabel?.text = "Test"
return cell
}
}

Answer Source

You are actually close to solution,

  1. Create an outlet for tableview reference
  2. Create a variable likeHoodList for holding result of GMSPlacesClient request.
  3. When GMSPlacesClient callback done and store result in likeHoodList and reload tableview.
  4. Don't forget to change cellForRowAt to write place name etc. and count of places is your tableview row count.
  5. in callback parameters placeLikelihoodList is a GMSPlaceLikelihoodList reference.
  6. GMSPlaceLikelihoodList has two properties, likelihoods and attributions
  7. likelihoods is an array of GMSPlaceLikelihood
  8. GMSPlaceLikelihood has two properties, place and likehood
  9. place is a GMSPlace reference which has properties about that place like name, placaeID, coordinate etc.

Here is a complete solution,

import UIKit
import GooglePlaces

class ViewController: UIViewController, UITableViewDataSource {

    var placesClient: GMSPlacesClient!
    var likeHoodList: GMSPlaceLikelihoodList?
    @IBOutlet var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.nearbyPlaces()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

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

            if let placeLikelihoodList = placeLikelihoodList {
                likeHoodList = placeLikelihoodList
                tableView.reloadData()
            }
        })
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if let likeHoodList = likeHoodList {
          return likeHoodList.likehoods.count
        }
        return 0
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell = UITableViewCell()
        var place = likeHoodList.likelihoods[indextPath.row].place //this is a GMSPlace object
        //https://developers.google.com/places/ios-api/reference/interface_g_m_s_place
        cell.textLabel?.text = place.name
        return cell
    }
}

Update,

It seems that you didn't init delegate, change viewdidload like this,

override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        self.nearbyPlaces()
    }
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download