import MapKit import CoreLocation import GoogleMobileAds import UserNotifications import UserMessagingPlatform class NewRunViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {     let locationManager = CLLocationManager()     let regionInMeters : Double = 200     var seconds = 0     private var timer: Timer?     private var distance = Measurement(value: 0, unit: UnitLength.meters)     private var locationList: [CLLocation] = []     var polyLine: MKPolyline = MKPolyline()     var isCounting : Bool = false     var randomArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]     var randomTime = [10.0, 95.0, 135.0,180.0,2370.0,4709.0]          @IBOutlet weak var MapView: MKMapView!     @IBOutlet weak var DistanceLabel: UILabel!     @IBOutlet weak var PaceLabel: UILabel!     @IBOutlet weak var TimeLabel: UILabel!     @IBOutlet weak var StartButtonLabel: UIButton!     @IBOutlet weak var ResetButtonOutlet: UIButton!     @IBOutlet weak var StopPauseButtonLabel: UIButton!     @IBOutlet weak var bannerView4: GADBannerView!          override func viewDidLoad() {         super.viewDidLoad()         checkLocationServices()         timer?.invalidate()         locationManager.stopUpdatingLocation()         StopPauseButtonLabel.titleLabel?.adjustsFontSizeToFitWidth = true                  bannerView4.adUnitID = "ca-app-pub-6331942799423798/9472120281"         bannerView4.rootViewController = self         bannerView4.load(GADRequest())         MapView.delegate = self                  NotificationCenter.default.addObserver(self, selector: #selector(pauseWhenInBackground(noti:)), name: UIApplication.willResignActiveNotification, object: nil)                  NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground(noti:)), name: UIApplication.didBecomeActiveNotification, object: nil)                  navigationItem.title = "Run Time"                  locationManager.allowsBackgroundLocationUpdates = true                  locationManager.pausesLocationUpdatesAutomatically = false     }          @IBAction func StartButton(_ sender: UIButton) {                  if isCounting == false {             locationList.removeAll()         }                  isCounting = true         ResetButtonOutlet.isHidden = true         StopPauseButtonLabel.isHidden = false         StartButtonLabel.isHidden = true         updateDisplay()         startLocationUpdates()         timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in           self.eachSecond()         }                  if CLLocationManager.authorizationStatus() == .authorizedAlways {             MapView.showsUserLocation = true         }                  else if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {             MapView.showsUserLocation = true         }                  else {            let alertController = UIAlertController(title: "Just to let you know...", message:                "Your location services are not enabled, you can still use the timer but the distance and pace won't show without your location. You can enable location services in your device settings.", preferredStyle: .alert)            alertController.addAction(UIAlertAction(title: "Dismiss", style: .default))            self.present(alertController, animated: true, completion: nil)         }          }          @IBAction func StopButtonLabel(_ sender: UIButton) {                  isCounting = false         StopPauseButtonLabel.isHidden = true         ResetButtonOutlet.isHidden = false         locationManager.stopUpdatingLocation()         StartButtonLabel.isHidden = false         timer?.invalidate()     }               @IBAction func ResetButton(_ sender: UIButton) {                  isCounting = false         StartButtonLabel.isHidden = false         seconds = 0         distance = Measurement(value: 0, unit: UnitLength.meters)         locationList.removeAll()         timer?.invalidate()         updateDisplay()         MapView.removeOverlays(MapView.overlays)         UserDefaults.standard.removeObject(forKey: "savedTime")         UserDefaults.standard.removeObject(forKey: "timeClosed")     }     func setUpLocationManager() {         locationManager.delegate = self         locationManager.desiredAccuracy = kCLLocationAccuracyBest     }          func centreViewOnUserLocation() {         if let location = locationManager.location?.coordinate {             let region = MKCoordinateRegion.init(center: location, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)             MapView.setRegion(region, animated: true)         }     }          func checkLocationServices() {         if CLLocationManager.locationServicesEnabled() {             setUpLocationManager()             checkLocationAuthorisation()         }                      else {         let alertController = UIAlertController(title: "Just so you know...", message:             "Sadly, your location services aren't enabled, change them in your settings to track your pace and distance.", preferredStyle: .alert)         alertController.addAction(UIAlertAction(title: "Dismiss", style: .default))         self.present(alertController, animated: true, completion: nil)         }     }          func openSettings(alert: UIAlertAction!) {         if let url = URL.init(string: UIApplication.openSettingsURLString) {             UIApplication.shared.open(url, options: [:], completionHandler: nil)         }     }          func checkLocationAuthorisation() {         switch CLLocationManager.authorizationStatus() {                      case.authorizedWhenInUse:                          MapView.showsUserLocation = true             centreViewOnUserLocation()             locationManager.startUpdatingLocation()             let alertController = UIAlertController(title: "Just to let you know...", message:                 "If you want to close the app or lock your phone while running, please go to device settings and enable 'Always' location", preferredStyle: .alert)                          alertController.addAction(UIAlertAction(title: "Dismiss", style: .default))             alertController.addAction(UIAlertAction(title: "Open Settings",                                           style: UIAlertAction.Style.default,                                           handler: openSettings))             self.present(alertController, animated: true, completion: nil)             break                      case.denied:                          let alertController = UIAlertController(title: "Just to let you know...", message:                 "Your location services are not enabled, you can still run but without your distance and pace. If you change your mind later you can enable location services in your device settings.", preferredStyle: .alert)             alertController.addAction(UIAlertAction(title: "Dismiss", style: .default))             self.present(alertController, animated: true, completion: nil)             break                  case.notDetermined:                          locationManager.requestWhenInUseAuthorization()             break                      case.restricted:                          let alertController = UIAlertController(title: "Just to let you know...", message:                 "Your location services are restricted, check your device settings.", preferredStyle: .alert)             alertController.addAction(UIAlertAction(title: "Dismiss", style: .default))             self.present(alertController, animated: true, completion: nil)             break                      case.authorizedAlways:             MapView.showsUserLocation = true             centreViewOnUserLocation()             locationManager.startUpdatingLocation()                      @unknown default:             break         }       }          func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {         guard let location = locations.last else { return }         let centre = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)         let region = MKCoordinateRegion.init(center: centre, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)         MapView.setRegion(region, animated: true)                    for newLocation in locations {             let howRecent = newLocation.timestamp.timeIntervalSinceNow             guard newLocation.horizontalAccuracy < 20 && abs(howRecent) < 10 else { continue }             if let lastLocation = locationList.last {               let delta = newLocation.distance(from: lastLocation)               distance = distance + Measurement(value: delta, unit: UnitLength.meters)                              let coordinates = [lastLocation.coordinate, newLocation.coordinate]               MapView.addOverlay(MKPolyline(coordinates: coordinates, count: 2))               let region = MKCoordinateRegion(center: newLocation.coordinate, latitudinalMeters: 200, longitudinalMeters: 200)               MapView.setRegion(region, animated: true)             }                              locationList.append(newLocation)           }     }     func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {         checkLocationAuthorisation()     }          func eachSecond() {       seconds += 1       centreViewOnUserLocation()       updateDisplay()     }     @objc private func updateDisplay() {       let formattedDistance = FormatDisplay.distance(distance)       let formattedTime = FormatDisplay.time(seconds)       let formattedPace = FormatDisplay.pace(distance: distance,                                              seconds: seconds,                                              outputUnit: UnitSpeed.minutesPerMile)                 DistanceLabel.text = "Distance:  \(formattedDistance)"         TimeLabel.text = "Time:  \(formattedTime)"         PaceLabel.text = "Pace:  \(formattedPace)"     }          private func startLocationUpdates() {       locationManager.delegate = self       locationManager.activityType = .fitness       locationManager.distanceFilter = 10       locationManager.startUpdatingLocation()       centreViewOnUserLocation()     }                  func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {                          if isCounting == true {                          guard let polyline = overlay as? MKPolyline else {                 return MKOverlayRenderer(overlay: overlay)             }             let renderer = MKPolylineRenderer(polyline: polyline)             renderer.strokeColor = .blue             renderer.lineWidth = 3             return renderer             }             return MKPolylineRenderer()         }          @objc func pauseWhenInBackground (noti : Notification) {         if isCounting == true {         UserDefaults.standard.removeObject(forKey: "isCounting")         UserDefaults.standard.removeObject(forKey: "savedSeconds")         UserDefaults.standard.removeObject(forKey: "timeClosed")         timer?.invalidate()         print(seconds)         let shared = UserDefaults.standard         shared.set(seconds, forKey: "savedSeconds")         let dateClosed = Date()         print(dateClosed)         shared.set(dateClosed, forKey: "timeClosed")         shared.set(isCounting, forKey: "isCounting")         }         else {                          UserDefaults.standard.set(isCounting, forKey: "isCounting")         }     }         @objc func willEnterForeground (noti : Notification) {             let isStillCounting = UserDefaults.standard.bool(forKey: "isCounting")             print(isStillCounting)             if isStillCounting == true {                 if let timeClosed = UserDefaults.standard.object(forKey: "timeClosed") as? Date {                     print(timeClosed)                                  let savedSeconds = UserDefaults.standard.integer(forKey: "savedSeconds")                 print(savedSeconds)                                  let dateOpened = Date()                                  let dateInterval = DateInterval.init(start: timeClosed, end: dateOpened)                                          print(dateInterval)                                          let differnce = dateInterval.duration                                          print(differnce)                                          seconds = Int(differnce) + savedSeconds                                          print(seconds)                                          timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in                       self.eachSecond()                     }                                          startLocationUpdates()                     updateDisplay()                     if CLLocationManager.authorizationStatus() == .authorizedAlways {                                 MapView.showsUserLocation = true                 }                                          else if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {                             MapView.showsUserLocation = true                     }                                          else {                         let alertController = UIAlertController(title: "Just to let you know...", message:                         "Your location services are not enabled, you can still use the timer but the distance and pace won't show without your location. You can enable location services in your device settings.", preferredStyle: .alert)                         alertController.addAction(UIAlertAction(title: "Dismiss", style: .default))                                          self.present(alertController, animated: true, completion: nil)                 }             }                             } else {}         }     }