ViewController

class ViewController : UIViewController, UIGestureRecognizerDelegate
extension ViewController: StopWatchDelegate
extension ViewController: PreferencesTableViewControllerDelegate
extension ViewController: GPXFilesTableViewControllerDelegate
extension ViewController: CLLocationManagerDelegate

Main View Controller of the Application. It is loaded when the application is launched

Displays a map and a set the buttons to control the tracking

  • Shall the map be centered on current user position? If yes, whenever the user moves, the center of the map too.

    Declaration

    Swift

    var followUser: Bool { get set }
  • TBD (not currently used)

    Declaration

    Swift

    var followUserBeforePinchGesture: Bool
  • location manager instance configuration

    Declaration

    Swift

    let locationManager: CLLocationManager
  • map

    Map View

    Declaration

    Swift

    var map: GPXMapView
  • Map View delegate

    Declaration

    Swift

    let mapViewDelegate: MapViewDelegate
  • Stop watch instance to control elapsed time

    Declaration

    Swift

    var stopWatch: StopWatch
  • Name of the last file that was saved (without extension)

    Declaration

    Swift

    var lastGpxFilename: String
  • Status variable that indicates if the app was sent to background.

    Declaration

    Swift

    var wasSentToBackground: Bool
  • Status variable that indicates if the location service auth was denied.

    Declaration

    Swift

    var isDisplayingLocationServicesDenied: Bool
  • Has the map any waypoint?

    Declaration

    Swift

    var hasWaypoints: Bool { get set }
  • Defines the different statuses regarding tracking current user location.

    See more

    Declaration

    Swift

    enum GpxTrackingStatus
  • Tells what is the current status of the Map Instance.

    Declaration

    Swift

    var gpxTrackingStatus: GpxTrackingStatus { get set }
  • Editing Waypoint Temporal Reference

    Declaration

    Swift

    var lastLocation: CLLocation?
  • Label with the title of the app

    Declaration

    Swift

    var appTitleLabel: UILabel
  • Image with the GPS signal

    Declaration

    Swift

    var signalImageView: UIImageView
  • Current GPS signal accuracy text (based on kSignalAccuracyX constants)

    Declaration

    Swift

    var signalAccuracyLabel: UILabel
  • Label that displays current latitude and longitude (lat,long)

    Declaration

    Swift

    var coordsLabel: UILabel
  • Displays current elapsed time (00:00)

    Declaration

    Swift

    var timeLabel: UILabel
  • Label that displays last known speed (in km/h)

    Declaration

    Swift

    var speedLabel: UILabel
  • Distance of the total segments tracked

    Declaration

    Swift

    var totalTrackedDistanceLabel: DistanceLabel
  • Distance of the current segment being tracked (since last time the Tracker button was pressed)

    Declaration

    Swift

    var currentSegmentDistanceLabel: DistanceLabel
  • Used to display in imperial (foot, miles, mph) or metric system (m, km, km/h)

    Declaration

    Swift

    var useImperial: Bool
  • Follow user button (bottom bar)

    Declaration

    Swift

    var followUserButton: UIButton
  • New pin button (bottom bar)

    Declaration

    Swift

    var newPinButton: UIButton
  • View GPX Files button

    Declaration

    Swift

    var folderButton: UIButton
  • View app about button

    Declaration

    Swift

    var aboutButton: UIButton
  • View preferences button

    Declaration

    Swift

    var preferencesButton: UIButton
  • Share current gpx file button

    Declaration

    Swift

    var shareButton: UIButton
  • Spinning Activity Indicator for shareButton

    Declaration

    Swift

    let shareActivityIndicator: UIActivityIndicatorView
  • Spinning Activity Indicator’s color

    Declaration

    Swift

    var shareActivityColor: UIColor
  • Reset map button (bottom bar)

    Declaration

    Swift

    var resetButton: UIButton
  • Start/Pause tracker button (bottom bar)

    Declaration

    Swift

    var trackerButton: UIButton
  • Save current track into a GPX file

    Declaration

    Swift

    var saveButton: UIButton
  • Check if device is notched type phone

    Declaration

    Swift

    var isIPhoneX: Bool
  • GPS signal image. Level 0 (no signal)

    Declaration

    Swift

    let signalImage0: UIImage?
  • GPS signal image. Level 1

    Declaration

    Swift

    let signalImage1: UIImage?
  • GPS signal image. Level 2

    Declaration

    Swift

    let signalImage2: UIImage?
  • GPS signal image. Level 3

    Declaration

    Swift

    let signalImage3: UIImage?
  • GPS signal image. Level 4

    Declaration

    Swift

    let signalImage4: UIImage?
  • GPS signal image. Level 5

    Declaration

    Swift

    let signalImage5: UIImage?
  • GPS signal image. Level 6

    Declaration

    Swift

    let signalImage6: UIImage?
  • Initializer. Just initializes the class vars/const

    Declaration

    Swift

    required init(coder aDecoder: NSCoder)
  • De initalize the ViewController.

    Current implementation removes notification observers

    Declaration

    Swift

    deinit
  • Handles status bar color as a result from iOS 13 appearance changes

    Declaration

    Swift

    override var preferredStatusBarStyle: UIStatusBarStyle { get }
  • Initializes the view. It adds the UI elements to the view.

    All the UI is built programatically on this method. Interface builder is not used.

    Declaration

    Swift

    override func viewDidLoad()

Add Constraints for views

  • Adds Constraints to subviews

    The constraints will ensure that subviews will be positioned correctly, when there are orientation changes, or iPad split view width changes.

    Declaration

    Swift

    func addConstraints(_ isIPhoneX: Bool)

    Parameters

    isIPhoneX

    if device is >= iPhone X, bottom gap will be zero

  • Adds constraints to subviews forming the app title bar (top bar)

    Declaration

    Swift

    func addConstraintsToAppTitleBar()
  • Adds constraints to subviews forming the informational labels (top right side; i.e. speed, elapse time labels)

    Declaration

    Swift

    func addConstraintsToTopInteractableElements()
  • Adds constraints to subviews forming the button bar (bottom session controls bar)

    Declaration

    Swift

    func addConstraintsToButtonBar(_ isIPhoneX: Bool)
  • Declaration

    Swift

    func addConstraintsToCompassView(_ view: MKCompassButton)
  • For handling compass location changes when orientation is switched.

    Declaration

    Swift

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
  • Will update polyline color when invoked

    Declaration

    Swift

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)
  • Updates polyline color

    Declaration

    Swift

    func updatePolylineColor()
  • Asks the system to notify the app on some events

    Current implementation requests the system to notify the app:

    1. whenever it enters background
    2. whenever it becomes active
    3. whenever it will terminate
    4. whenever it receives a file from Apple Watch
    5. whenever it should load file from Core Data recovery mechanism

    Declaration

    Swift

    func addNotificationObservers()
  • To update appearance when mapView requests to do so

    Declaration

    Swift

    @objc
    func updateAppearance()
  • Presents alert when file received from Apple Watch

    Declaration

    Swift

    @objc
    func presentReceivedFile(_ notification: Notification)
  • returns a string with the format of current date dd-MMM-yyyy-HHmm’ (20-Jun-2018-1133)

    Declaration

    Swift

    func defaultFilename() -> String
  • Declaration

    Swift

    @objc
    func loadRecoveredFile(_ notification: Notification)
  • Called when the application Becomes active (background -> foreground) this function verifies if it has permissions to get the location.

    Declaration

    Swift

    @objc
    func applicationDidBecomeActive()
  • Actions to do in case the app entered in background

    In current implementation if the app is not tracking it requests the OS to stop sharing the location to save battery.

    Declaration

    Swift

    @objc
    func didEnterBackground()
  • Actions to do when the app will terminate

    In current implementation it removes all the temporary files that may have been created

    Declaration

    Swift

    @objc
    func applicationWillTerminate()
  • Displays the view controller with the list of GPX Files.

    Declaration

    Swift

    @objc
    func openFolderViewController()
  • Displays the view controller with the About information.

    Declaration

    Swift

    @objc
    func openAboutViewController()
  • Opens Preferences table view controller

    Declaration

    Swift

    @objc
    func openPreferencesTableViewController()
  • Opens an Activity View Controller to share the file

    Declaration

    Swift

    @objc
    func openShare()
  • Displays spinning activity indicator for share button when true

    Declaration

    Swift

    func shouldShowShareActivityIndicator(_ isTrue: Bool)
  • After invoking this fuction, the map will not be centered on current user position.

    Declaration

    Swift

    @objc
    func stopFollowingUser(_ gesture: UIPanGestureRecognizer)
  • UIGestureRecognizerDelegate required for stopFollowingUser

    Declaration

    Swift

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
                           shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool
  • If user long presses the map for a while a Pin (Waypoint/Annotation) will be dropped at that point.

    Declaration

    Swift

    @objc
    func addPinAtTappedLocation(_ gesture: UILongPressGestureRecognizer)
  • Does nothing in current implementation.

    Declaration

    Swift

    func pinchGesture(_ gesture: UIPinchGestureRecognizer)
  • It adds a Pin (Waypoint/Annotation) to current user location.

    Declaration

    Swift

    @objc
    func addPinAtMyLocation()
  • Declaration

    Swift

    @objc
    func followButtonTroggler()
  • Triggered when reset button was tapped.

    It sets map to status .notStarted which clears the map.

    Declaration

    Swift

    @objc
    func resetButtonTapped()
  • Main Start/Pause Button was tapped.

    It sets the status to tracking or paused.

    Declaration

    Swift

    @objc
    func trackerButtonTapped()
  • Triggered when user taps on save Button

    It prompts the user to set a name of the file.

    Declaration

    Swift

    @objc
    func saveButtonTapped(withReset: Bool = false)
  • There was a memory warning. Right now, it does nothing but to log a line.

    Declaration

    Swift

    override func didReceiveMemoryWarning()
  • Checks the location services status

    • Are location services enabled (access to location device wide)? If not => displays an alert
    • Are location services allowed to this app? If not => displays an alert

    Seealso

    displayLocationServicesDisabledAlert, displayLocationServicesDeniedAlert

    Declaration

    Swift

    func checkLocationServicesStatus()
  • Displays an alert that informs the user that location services are disabled.

    When location services are disabled is for all applications, not only this one.

    Declaration

    Swift

    func displayLocationServicesDisabledAlert()
  • Displays an alert that informs the user that access to location was denied for this app (other apps may have access). It also dispays a button allows the user to go to settings to activate the location.

    Declaration

    Swift

    func displayLocationServicesDeniedAlert()
  • force dark mode (i.e. white text, if map content is known to be dark)

    Declaration

    Swift

    func textColorAdaptations()

StopWatchDelegate

PreferencesTableViewControllerDelegate

  • Update the activity type that the location manager is using.

    When user changes the activity type in preferences, this function is invoked to update the activity type of the location manager.

    Declaration

    Swift

    func didUpdateActivityType(_ newActivityType: Int)
  • Updates the tileServer the map is using.

    If user enters preferences and he changes his preferences regarding the tileServer, the map of the main ViewController needs to be aware of it.

    PreferencesTableViewController informs the main ViewController through this delegate.

    Declaration

    Swift

    func didUpdateTileServer(_ newGpxTileServer: Int)
  • If user changed the setting of using cache, through this delegate, the main ViewController informs the map to behave accordingly.

    Declaration

    Swift

    func didUpdateUseCache(_ newUseCache: Bool)
  • Declaration

    Swift

    func didUpdateUseImperial(_ newUseImperial: Bool)
  • Loads the selected GPX File into the map.

    Resets whatever estatus was before.

    Declaration

    Swift

    func didLoadGPXFileWithName(_ gpxFilename: String, gpxRoot: GPXRoot)

CLLocationManagerDelegate

  • Location manager calls this func to inform there was an error.

    It performs the following actions:

    • Sets coordsLabel with kNotGettingLocationText, signal accuracy to kUnknownAccuracyText and signalImageView to signalImage0.
    • If the error code is CLError.denied it calls checkLocationServicesStatus

    Declaration

    Swift

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error)
  • Updates location accuracy and map information when user is in a new position

    Declaration

    Swift

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
  • When there is a change on the heading (direction in which the device oriented) it makes a request to the map to updathe the heading indicator (a small arrow next to user location point)

    Declaration

    Swift

    func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading)
  • Called by the system when CLLocationManager is created and when the user makes a permission choice

    We handle this delegate callback so that we can check if the user has allowed location access, else we show a warning

    Declaration

    Swift

    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager)