// // MainViewController.swift // Guibe // // Created by Max Hunt on 28/05/2019. // Copyright © 2019 8. All rights reserved. // import UIKit import AVKit import MapKit import CoreLocation import AVFoundation class MainViewController: UIViewController, AVAudioPlayerDelegate, myProtocol { // DELETE let defaults = UserDefaults.standard // DELETE let appDelegate = UIApplication.shared.delegate as! AppDelegate let locationManager = CLLocationManager() var currentCoordinate: CLLocationCoordinate2D! var player = AVAudioPlayer() var steps = [MKRoute.Step]() var stepCounter = 0 var previousDistanceToWaypoint: Double = 1000 var distanceToNextCoord: Double = 1000 var startedNavigation: Bool = false var toLocationId: Int = -1 // OUTLETS--------------OUTLETS @IBOutlet weak var menuWindowView: UIView! @IBOutlet weak var menuView: UIView! @IBOutlet weak var menuBtn: UIButton! @IBOutlet weak var dismissBtn: UIButton! // --------------------- @IBOutlet weak var searchBarBg: UIButton! @IBOutlet weak var searchView: UIView! @IBOutlet weak var searchBar: UISearchBar! @IBOutlet weak var micBtn: UIButton! // --------------------- @IBOutlet weak var mapView: MKMapView! // OUTLETS--------------OUTLETS // ACTIONS--------------ACTIONS @IBAction func menuBtnPressed(_ sender: Any) { UIView.animate(withDuration: 0.2, animations: {self.menuWindowView.alpha = 1.0}) dismissBtn.isHidden = false } @IBAction func micBtnPressed(_ sender: Any) { } @IBAction func dismissBtnPressed(_ sender: Any) { UIView.animate(withDuration: 0.2, animations: {self.menuWindowView.alpha = 0.0}) dismissBtn.isHidden = true } @IBAction func settingsBtnPressed(_ sender: Any) { } // ACTIONS--------------ACTIONS override func viewDidLoad() { super.viewDidLoad() searchBar.delegate = self searchBarBg.layer.shadowColor = UIColor.black.cgColor searchBarBg.layer.cornerRadius = 10 searchBarBg.layer.shadowOffset = CGSize(width: 5, height: 7) searchBarBg.layer.shadowRadius = 10 searchBarBg.layer.shadowOpacity = 0.2 menuWindowView.layer.shadowColor = UIColor.black.cgColor menuWindowView.layer.cornerRadius = 13 menuWindowView.layer.shadowOffset = CGSize(width: 5, height: 7) menuWindowView.layer.shadowRadius = 10 menuWindowView.layer.shadowOpacity = 0.2 mapView.delegate = self locationManager.delegate = self locationManager.desiredAccuracy = kCLLocationAccuracyBest locationManager.startUpdatingLocation() } //END OF VIEW DID LOAD func getDirections(to destination: MKMapItem) { let sourcePlacemark = MKPlacemark(coordinate: currentCoordinate) let sourceMapItem = MKMapItem(placemark: sourcePlacemark) let directionsRequest = MKDirections.Request() directionsRequest.source = sourceMapItem directionsRequest.destination = destination directionsRequest.transportType = .walking let directions = MKDirections(request: directionsRequest) directions.calculate { (response, _) in guard let response = response else { return } // self.appDelegate.navigationResults = response // let resultsViewController = self.storyboard?.instantiateViewController(withIdentifier: "resultsScreen") as! TableViewController // resultsViewController.searchResults = response // resultsViewController.modalTransitionStyle = .coverVertical // self.present(resultsViewController, animated: true, completion: nil) guard let primaryRoute = response.routes.first else { return } self.mapView.addOverlay(primaryRoute.polyline) self.steps = primaryRoute.steps for i in 0 ..< primaryRoute.steps.count { let step = primaryRoute.steps[i] print(step.instructions) print(step.distance) // -----------------------------Geofencing setup let region = CLCircularRegion(center: step.polyline.coordinate, radius: 15, identifier: "\(i)") // self.locationManager.startMonitoring(for: region) // -----------------------------Geofencing setup let circle = MKCircle(center: region.center, radius: region.radius) self.mapView.addOverlay(circle) } self.startedNavigation = true self.stepCounter += 1 } } func startNavigation(toPlace: MKMapItem){ getDirections(to: toPlace) } } //END OF CLASS extension MainViewController: CLLocationManagerDelegate { func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { guard let currentLocation = locations.first else { return } currentCoordinate = currentLocation.coordinate mapView.userTrackingMode = .follow if startedNavigation == true { let nextStep = steps[stepCounter] let nextCoord = CLLocation(latitude: nextStep.polyline.coordinate.latitude, longitude: nextStep.polyline.coordinate.longitude) distanceToNextCoord = currentLocation.distance(from: nextCoord) if distanceToNextCoord < previousDistanceToWaypoint { previousDistanceToWaypoint = currentLocation.distance(from: nextCoord) } if distanceToNextCoord > previousDistanceToWaypoint + 10 { previousDistanceToWaypoint = distanceToNextCoord - 5 playTurnArd() } if distanceToNextCoord < 15 { stepCounter += 1 if stepCounter < steps.count { // let currentStep = steps[stepCounter] let message = "\(steps[stepCounter-1].instructions)" let maneuverCommand = String(message.prefix(10)) switch (maneuverCommand) { case "Turn right": playRight() break; case "Bear right": playRight() break; case "Turn left ": playLeft() break; case "Bear left": playLeft() break; case "The destin": playDone() default: playErr() break; } // let speechUtterance = AVSpeechUtterance(string: message) // speechSynthesizer.speak(speechUtterance) previousDistanceToWaypoint = 1000 } else { // let speechUtterance = AVSpeechUtterance(string: message) // speechSynthesizer.speak(speechUtterance) stepCounter = 0 previousDistanceToWaypoint = 1000 searchBar.isHidden = false // locationManager.monitoredRegions.forEach({ self.locationManager.stopMonitoring(for: $0) }) } } } } func playRight(){ // currentStepLbl.text = "COM: RIGHT" let path = Bundle.main.path(forResource: "xright", ofType : "mp3")! let url = URL(fileURLWithPath : path) do { player = try AVAudioPlayer(contentsOf: url) player.delegate = self player.play() } catch {} } func playLeft(){ // currentStepLbl.text = "COM: LEFT" let path = Bundle.main.path(forResource: "xleft", ofType : "mp3")! let url = URL(fileURLWithPath : path) do { player = try AVAudioPlayer(contentsOf: url) player.delegate = self player.play() } catch {} } func playErr(){ // currentStepLbl.text = "COM: ERROR!!!" return } func playTurnArd(){ // currentStepLbl.text = "COM: UTURN" let path = Bundle.main.path(forResource: "xboth", ofType : "mp3")! let url = URL(fileURLWithPath : path) do { player = try AVAudioPlayer(contentsOf: url) player.delegate = self player.play() } catch {} } func playDone(){ // currentStepLbl.text = "COM: DONE" } } extension MainViewController: UISearchBarDelegate { func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { searchBar.endEditing(true) //HIDES LE KEYBOARD let localSearchRequest = MKLocalSearch.Request() localSearchRequest.naturalLanguageQuery = searchBar.text let region = MKCoordinateRegion(center: currentCoordinate, span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)) localSearchRequest.region = region let localSearch = MKLocalSearch(request: localSearchRequest) localSearch.start { (response, _) in guard let response = response else { return } let resultsViewController = self.storyboard?.instantiateViewController(withIdentifier: "resultsScreen") as! TableViewController resultsViewController.searchResults = response.mapItems resultsViewController.modalTransitionStyle = .coverVertical resultsViewController.myProtocol = self self.present(resultsViewController, animated: true, completion: nil) // guard let firstMapItem = response.mapItems.first else { return } // self.getDirections(to: firstMapItem) } } } extension MainViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { if overlay is MKPolyline { let renderer = MKPolylineRenderer(overlay: overlay) renderer.strokeColor = .blue renderer.alpha = 0.7 renderer.lineWidth = 10 return renderer } if overlay is MKCircle { let renderer = MKCircleRenderer(overlay: overlay) renderer.strokeColor = .red renderer.fillColor = .red renderer.alpha = 0.4 return renderer } return MKOverlayRenderer() } }