FindPlaceLikelihoodListViewController.swift 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright 2020 Google LLC. All rights reserved.
  2. //
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
  5. // file except in compliance with the License. You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software distributed under
  10. // the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
  11. // ANY KIND, either express or implied. See the License for the specific language governing
  12. // permissions and limitations under the License.
  13. import CoreLocation
  14. import GooglePlaces
  15. import UIKit
  16. /// Demo that exposes the findPlaceLikelihoodsForLocation API. Please refer to
  17. /// https://developers.google.com/places/ios-sdk/current-place
  18. class FindPlaceLikelihoodListViewController: UIViewController {
  19. private let cellIdentifier = "LikelihoodCellIdentifier"
  20. private let padding: CGFloat = 20
  21. private var placeLikelihoods: [GMSPlaceLikelihood]?
  22. private lazy var locationManager: CLLocationManager = {
  23. let manager = CLLocationManager()
  24. manager.delegate = self
  25. return manager
  26. }()
  27. private lazy var errorLabel: UILabel = UILabel()
  28. private lazy var tableView: UITableView = {
  29. let tableView = UITableView()
  30. tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellIdentifier)
  31. tableView.dataSource = self
  32. return tableView
  33. }()
  34. private lazy var placeClient: GMSPlacesClient = GMSPlacesClient.shared()
  35. private var areLocationServicesEnabledAndAuthorized: Bool {
  36. guard CLLocationManager.locationServicesEnabled() else {
  37. return false
  38. }
  39. let status = CLLocationManager.authorizationStatus()
  40. return status == .authorizedAlways || status == .authorizedWhenInUse
  41. }
  42. override func viewDidLoad() {
  43. super.viewDidLoad()
  44. navigationController?.navigationBar.isTranslucent = false
  45. view.backgroundColor = .white
  46. let button = UIButton()
  47. button.setTitle("Find from current location", for: .normal)
  48. button.setTitleColor(.blue, for: .normal)
  49. button.addTarget(
  50. self, action: #selector(loadLikelihoodFromCurrentLocation), for: .touchUpInside)
  51. button.translatesAutoresizingMaskIntoConstraints = false
  52. view.addSubview(button)
  53. NSLayoutConstraint.activate([
  54. button.topAnchor.constraint(equalTo: view.topAnchor, constant: padding),
  55. button.heightAnchor.constraint(equalToConstant: 40),
  56. button.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
  57. button.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding),
  58. ])
  59. errorLabel.isHidden = true
  60. errorLabel.translatesAutoresizingMaskIntoConstraints = false
  61. view.addSubview(errorLabel)
  62. NSLayoutConstraint.activate([
  63. errorLabel.topAnchor.constraint(equalTo: button.bottomAnchor, constant: padding),
  64. errorLabel.heightAnchor.constraint(equalToConstant: 40),
  65. errorLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
  66. errorLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding),
  67. ])
  68. tableView.isHidden = true
  69. tableView.translatesAutoresizingMaskIntoConstraints = false
  70. view.addSubview(tableView)
  71. NSLayoutConstraint.activate([
  72. tableView.topAnchor.constraint(equalTo: button.bottomAnchor, constant: padding),
  73. tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
  74. tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
  75. tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
  76. ])
  77. loadLikelihoodFromCurrentLocation()
  78. }
  79. @objc func loadLikelihoodFromCurrentLocation() {
  80. guard areLocationServicesEnabledAndAuthorized else {
  81. locationManager.requestWhenInUseAuthorization()
  82. return
  83. }
  84. locationManager.startUpdatingLocation()
  85. placeClient.findPlaceLikelihoodsFromCurrentLocation(withPlaceFields: .all) {
  86. [weak self] (list, error) -> Void in
  87. guard let self = self else { return }
  88. guard error == nil else {
  89. self.errorLabel.text = "There was an error fetching likelihoods."
  90. self.errorLabel.isHidden = false
  91. self.tableView.isHidden = true
  92. return
  93. }
  94. self.placeLikelihoods = list?.filter { likelihood in
  95. !(likelihood.place.name?.isEmpty ?? true)
  96. }
  97. self.errorLabel.isHidden = true
  98. self.tableView.isHidden = false
  99. self.tableView.reloadData()
  100. }
  101. }
  102. }
  103. extension FindPlaceLikelihoodListViewController: CLLocationManagerDelegate {
  104. func locationManager(
  105. _ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus
  106. ) {
  107. if status == .authorizedWhenInUse {
  108. // Retry current location fetch once user enables Location Services.
  109. loadLikelihoodFromCurrentLocation()
  110. } else {
  111. errorLabel.text = "Please make sure location services are enabled."
  112. }
  113. }
  114. }
  115. extension FindPlaceLikelihoodListViewController: UITableViewDataSource {
  116. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  117. guard let likelihoods = placeLikelihoods else {
  118. return 0
  119. }
  120. return likelihoods.count
  121. }
  122. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  123. let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)
  124. cell.textLabel?.numberOfLines = 0
  125. cell.selectionStyle = .none
  126. guard let likelihoods = placeLikelihoods else {
  127. return cell
  128. }
  129. if likelihoods.count >= 0 && indexPath.row < likelihoods.count {
  130. cell.textLabel?.text = likelihoods[indexPath.row].place.name
  131. }
  132. return cell
  133. }
  134. }