Skip to content

Instantly share code, notes, and snippets.

@PerryRose
Created July 22, 2021 06:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PerryRose/561ab72a08b5e463ab1588bfcb84cf3f to your computer and use it in GitHub Desktop.
Save PerryRose/561ab72a08b5e463ab1588bfcb84cf3f to your computer and use it in GitHub Desktop.
SIT314 A2 - iOS App
//
// ViewController.swift
// GPSTracker
//
// Created by Perry Rose on 22/7/21.
//
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var timerLabel: UILabel!
@IBOutlet weak var statusLabel: UILabel!
@IBOutlet weak var coordsRecordedLabel: UILabel!
struct Coord: Codable {
let lat: Double
let lng: Double
}
var coords = [Coord]()
var isTracking: Bool = false
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Request authorisation
locationManager.requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
// Set delegate
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
}
@IBAction func startTracking(_ sender: Any) {
if (!isTracking) {
// Start tracking user
isTracking = true;
statusLabel.text = "Current Status: Tracking"
locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
// Alert user for any location errors
alertUser(title: "Error", message: "There was an error getting your GPS data")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if (isTracking) {
if let location = locations.first {
// Get current location and add it to coords array
coords.append(Coord(lat: location.coordinate.latitude, lng: location.coordinate.longitude))
// Update label
coordsRecordedLabel.text = "Coord Recorded: \(coords.count)"
}
}
}
@IBAction func stopTracking(_ sender: Any) {
if (isTracking) {
// Stop Tracking
isTracking = false;
statusLabel.text = "Current Status: Not Tracking"
}
}
@IBAction func clearTracking(_ sender: Any) {
if (!isTracking) {
// Remove coords from array
coords.removeAll()
coordsRecordedLabel.text = "Coords Recorded: 0"
alertUser(title: "Success", message: "Your current tracking data has been removed")
}
else {
alertUser(title: "Cannot clear tracking", message: "Please stop tracking before clearing tracking")
}
}
@IBAction func exportCurrentRun(_ sender: Any) {
if (!isTracking) {
uploadData()
}
else {
alertUser(title: "Cannot upload data", message: "Please stop the tracking before uploading the data")
}
}
func uploadData() {
// Encode run data
guard let uploadData = try? JSONEncoder().encode(coords) else {
alertUser(title: "Error", message: "There was an error with the JSON encoder")
return
}
// Prepare request
let url = URL(string: "https://api.jsonbin.io/v3/b")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("$2b$10$O3vibr5wNWg3eVTsg79HYO1Cs3Jcz7rJkwA6pf5phIVhDyVLwvctq", forHTTPHeaderField: "X-Master-Key")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("GPSTrackingData", forHTTPHeaderField: "X-Bin-Name")
// Upload JSON data
let task = URLSession.shared.uploadTask(with: request, from: uploadData) { data, response, error in
if error != nil {
self.alertUser(title: "Cannot upload data", message: "There was an error uploading the data")
return
}
guard let response = response as? HTTPURLResponse,
(200...299).contains(response.statusCode) else {
self.alertUser(title: "Cannot upload data", message: "There was a server error and the data was not uploaded")
return
}
if let mimeType = response.mimeType,
mimeType == "application/json",
let data = data,
let dataString = String(data: data, encoding: .utf8) {
print(dataString)
self.alertUser(title: "Success", message: "The data was successfully uploaded to JSONBIN.io")
}
}
task.resume()
}
func alertUser(title: String, message: String) {
// Alert on main thread to prevent errors from inside URLSession.shared.uploadTask call
DispatchQueue.main.async {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Okay", style: .default, handler: nil))
self.present(alert, animated: true)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment