-
-
Save satriawarn/173be342d498019fc8004616a000e31e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import GoogleMaps | |
import GooglePlaces | |
import CoreLocation | |
class ViewController: UIViewController { | |
var locationManager: CLLocationManager! | |
var resultsViewController: GMSAutocompleteResultsViewController? | |
var searchController: UISearchController? | |
var resultView: UITextView? | |
var currentLocation: CLLocation? | |
var placesClient: GMSPlacesClient! | |
@IBOutlet var mapView: GMSMapView! | |
override func viewDidLoad() { | |
//searchbox | |
resultsViewController = GMSAutocompleteResultsViewController() | |
resultsViewController?.delegate = self | |
searchController = UISearchController(searchResultsController: resultsViewController) | |
searchController?.searchResultsUpdater = resultsViewController | |
searchController?.searchBar.sizeToFit() | |
navigationItem.titleView = searchController?.searchBar | |
// When UISearchController presents the results view, present it in | |
// this view controller, not one further up the chain. | |
definesPresentationContext = true | |
// Prevent the navigation bar from being hidden when searching. | |
searchController?.hidesNavigationBarDuringPresentation = false | |
placesClient = GMSPlacesClient.shared() | |
} | |
} | |
/** | |
This extension inherit GMSAutoCompleteResult to handle | |
text from search bar, when user click one of result placemark | |
it will fetching directions api google maps | |
**/ | |
extension ViewController: GMSAutocompleteResultsViewControllerDelegate { | |
func resultsController(_ resultsController: GMSAutocompleteResultsViewController, | |
didAutocompleteWith place: GMSPlace) { | |
searchController?.isActive = false | |
fetchRoute(from: locationManager.location!.coordinate, to: place.coordinate) | |
} | |
func fetchRoute(from source: CLLocationCoordinate2D, to destination: CLLocationCoordinate2D) { | |
//fetching google maps api with parameters coordinate origin and coordinate destination | |
let url = URL(string: "https://maps.googleapis.com/maps/api/directions/json?origin=\(source.latitude),\(source.longitude)&destination=\(destination.latitude),\(destination.longitude)&sensor=false&mode=driving&key=\(googleApiKey)")! | |
//process the result from fetching api | |
URLSession.shared.dataTask(with: url, completionHandler: { | |
(data, response, error) in | |
if(error != nil){ | |
print("error") | |
}else{ | |
DispatchQueue.main.async { | |
self.mapView.clear() | |
} | |
do{ | |
//get the json from the result | |
let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String : AnyObject] | |
let routes = json["routes"] as! NSArray | |
OperationQueue.main.addOperation({ | |
for route in routes { | |
if let legs = (route as AnyObject) as? [String : AnyObject]{ | |
let legs = legs["legs"] as! [[String : AnyObject]] | |
for leg in legs { | |
let durations:NSDictionary = (leg as NSDictionary).value(forKey: "duration") as! NSDictionary | |
let textDuration = durations.object(forKey: "text") | |
let distance:NSDictionary = (leg as NSDictionary).value(forKey: "distance") as! NSDictionary | |
let textDistance = distance.object(forKey: "text") | |
self.showEstimate(distance: textDistance as! String, duration: textDuration as! String) | |
let end_location: NSDictionary = (leg as NSDictionary).value(forKey: "end_location") as! NSDictionary | |
let textLat = end_location.object(forKey: "lat") | |
let textLong = end_location.object(forKey: "lng") | |
self.showPinPoint(latitude: textLat as! Double, longitude: textLong as! Double) | |
} | |
} | |
let routeOverviewPolyline:NSDictionary = (route as! NSDictionary).value(forKey: "overview_polyline") as! NSDictionary | |
let points = routeOverviewPolyline.object(forKey: "points") | |
self.drawPath(from: points as! String) | |
} | |
}) | |
} catch let error as NSError{ | |
print("error:\(error)") | |
} | |
} | |
}).resume() | |
} | |
/** | |
This function used to generate the polyline | |
using parameters of points from overview_polyline | |
also move camera for user visibility | |
**/ | |
func drawPath(from polyStr: String){ | |
let path = GMSPath.init(fromEncodedPath: polyStr) | |
let polyline = GMSPolyline.init(path: path) | |
. . . | |
} | |
/** | |
This function used to give user information | |
about the distance and duration | |
**/ | |
func showEstimate(distance: String, duration: String){ | |
. . . | |
} | |
/** | |
This function used to dropped pin | |
in location that have been choosen by user | |
**/ | |
func showPinPoint(latitude lat: Double, longitude long: Double){ | |
. . . | |
} | |
func resultsController(_ resultsController: GMSAutocompleteResultsViewController, | |
didFailAutocompleteWithError error: Error){ | |
// TODO: handle the error. | |
print("Error: ", error.localizedDescription) | |
} | |
// 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 | |
} | |
} | |
extension ViewController: CLLocationManagerDelegate { | |
// Handle incoming location events. | |
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { | |
. . . | |
} | |
// Handle authorization for the location manager. | |
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { | |
// Check accuracy authorization | |
let accuracy = manager.accuracyAuthorization | |
switch accuracy { | |
case .fullAccuracy: | |
. . . | |
case .reducedAccuracy: | |
. . . | |
@unknown default: | |
fatalError() | |
} | |
// Handle authorization status | |
switch status { | |
case .restricted: | |
. . . | |
case .denied: | |
. . . | |
case .notDetermined: | |
. . . | |
case .authorizedAlways, .authorizedWhenInUse : | |
. . . | |
@unknown default: | |
fatalError() | |
} | |
} | |
// Handle location manager errors. | |
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { | |
locationManager.stopUpdatingLocation() | |
print("Error: \(error)") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment