|
@@ -12,7 +12,14 @@ import CoreData
|
|
|
|
|
|
class ViewController: UIViewController {
|
|
|
|
|
|
+ struct GPS_POS_LOG: Codable {
|
|
|
+ var latitude: Double
|
|
|
+ var longitude: Double
|
|
|
+ var ts: String
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
+ @IBOutlet weak var latestTSSent: UILabel!
|
|
|
@IBOutlet weak var noOfRxGPSPos: UILabel!
|
|
|
@IBOutlet weak var noOfSentGPSToServer: UILabel!
|
|
|
@IBOutlet weak var pauseSwitch: UISwitch!
|
|
@@ -28,8 +35,8 @@ class ViewController: UIViewController {
|
|
|
|
|
|
let appDelegate = UIApplication.shared.delegate as! AppDelegate
|
|
|
|
|
|
+ var latestDateSuccSent: Date = Date(timeIntervalSinceReferenceDate: -123456789.0)
|
|
|
|
|
|
-
|
|
|
override func viewDidLoad() {
|
|
|
super.viewDidLoad()
|
|
|
locationManager = CLLocationManager()
|
|
@@ -44,57 +51,105 @@ class ViewController: UIViewController {
|
|
|
|
|
|
}
|
|
|
|
|
|
- func convertStartDate(StartDate: Date) -> String {
|
|
|
-
|
|
|
- let dateFormatter = DateFormatter()
|
|
|
- dateFormatter.timeZone = TimeZone.current
|
|
|
- dateFormatter.dateFormat = "yyy-MM-dd' 'HH:mm:ss"
|
|
|
- let dateString = dateFormatter.string(from: StartDate)
|
|
|
- //dateFormatter.dateFormat = "yyy-MM-dd HH:mm:ss +0000"
|
|
|
- //let date = dateFormatter.date(from: dateString)
|
|
|
- return dateString
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
+ // This timer is used to send data to the back-end server every 60 seconds
|
|
|
+ // Data source is the core data DB
|
|
|
func setupTimer() {
|
|
|
|
|
|
_ = Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { [self] timer in
|
|
|
|
|
|
- print("New Timer fired!")
|
|
|
+ var latestDate: Date = Date(timeIntervalSinceReferenceDate: -123456789.0)
|
|
|
|
|
|
let cnxt = self.appDelegate.persistentContainer.viewContext
|
|
|
let request: NSFetchRequest<GPS> = GPS.fetchRequest()
|
|
|
+ let myPredicate = NSPredicate(format: "ts > %@", latestDateSuccSent as CVarArg)
|
|
|
+
|
|
|
+ request.predicate = myPredicate
|
|
|
|
|
|
do {
|
|
|
let fd = try cnxt.fetch(request)
|
|
|
- print( "Cnt:" + String(fd.count) )
|
|
|
+ print( "Timer: DB Request returned:" + String(fd.count) )
|
|
|
|
|
|
- var positions: [GPS_POS_LOG] = []
|
|
|
-
|
|
|
- fd.forEach { row in
|
|
|
- let ts = self.convertStartDate(StartDate: row.ts!)
|
|
|
- let gpsPosLog = GPS_POS_LOG(latitude:row.latitude,longitude: row.longitud,ts: ts)
|
|
|
- positions.append(gpsPosLog)
|
|
|
- cnxt.delete(row)
|
|
|
- self.noOfSentToServer += 1
|
|
|
+ if( fd.count > 0 ) {
|
|
|
+ var positions: [GPS_POS_LOG] = []
|
|
|
+
|
|
|
+ fd.forEach { row in
|
|
|
+ let ts = convertStartDate(StartDate: row.ts!)
|
|
|
+ let gpsPosLog = GPS_POS_LOG(latitude:row.latitude,longitude: row.longitud,ts: ts)
|
|
|
+ positions.append(gpsPosLog)
|
|
|
+ //cnxt.delete(row) // This row deletes the row in the DB
|
|
|
+ self.noOfSentToServer += 1
|
|
|
+
|
|
|
+ if( row.ts! > latestDate ) {
|
|
|
+ latestDate = row.ts!; // Save the latest date
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sendToHttpServer(gpsPosLog: positions, latestDate: latestDate)
|
|
|
+ noOfSentGPSToServer.text = String(noOfSentToServer) // Update GUI
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ print("Timer: No data to send to back-end");
|
|
|
}
|
|
|
- sendToHttpServer(gpsPosLog: positions)
|
|
|
- noOfSentGPSToServer.text = String(noOfSentToServer)
|
|
|
|
|
|
} catch let error as NSError {
|
|
|
- print("Could not fetch. \(error), \(error.userInfo)")
|
|
|
+ print("Timer: Could not fetch. \(error), \(error.userInfo)")
|
|
|
}
|
|
|
if( self.trackingActivateSwitch.isOn == false ) {
|
|
|
timer.invalidate()
|
|
|
- print("Stopping Timer")
|
|
|
+ print("Timer: Stopping Timer")
|
|
|
}
|
|
|
+
|
|
|
+ latestTSSent.text = convertStartDate(StartDate: latestDate)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ func sendToHttpServer(gpsPosLog: [GPS_POS_LOG], latestDate: Date) {
|
|
|
+
|
|
|
+ let jsonEncoder = JSONEncoder()
|
|
|
+ jsonEncoder.outputFormatting = .prettyPrinted
|
|
|
+
|
|
|
+ var uploadData:Data?
|
|
|
+ do {
|
|
|
+ uploadData = try jsonEncoder.encode(gpsPosLog)
|
|
|
+ } catch {
|
|
|
+ print(error.localizedDescription)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //print( gpsPosLog )
|
|
|
+
|
|
|
+ let url = URL(string: "http://chef.maya.se/gpsapi/registerGPSlocation.php")!
|
|
|
+ var request = URLRequest(url: url)
|
|
|
+ request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
|
+ request.httpMethod = "POST"
|
|
|
+
|
|
|
+ let task = URLSession.shared.uploadTask(with: request, from: uploadData) { data, response, error in
|
|
|
+ if let error = error {
|
|
|
+ print ("HTTP: error: \(error)")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ guard let response = response as? HTTPURLResponse,
|
|
|
+ (200...299).contains(response.statusCode) else {
|
|
|
+ print ("HTTP: 200-299 server error")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if let mimeType = response.mimeType,
|
|
|
+ mimeType == "text/html",
|
|
|
+ let data = data,
|
|
|
+ let dataString = String(data: data, encoding: .utf8) {
|
|
|
+ print ("HTTP: got data: \(dataString)")
|
|
|
+ print ("HTTP: Latest date sent: " + self.convertStartDate(StartDate: latestDate))
|
|
|
+ //self.latestTSSent.text = self.convertStartDate(StartDate: latestDate)
|
|
|
+ self.latestDateSuccSent = latestDate
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ print("HTTP: KALLE:" + String(response.mimeType!))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ task.resume()
|
|
|
|
|
|
-
|
|
|
- @objc func fireTimer() {
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@IBAction func tackingPauseChanged(_ sender: UISwitch) {
|
|
|
print("Pause-Switch Changed !")
|
|
|
switch sender.isOn {
|
|
@@ -119,6 +174,7 @@ class ViewController: UIViewController {
|
|
|
} catch {
|
|
|
// Error Handling
|
|
|
}
|
|
|
+ latestDateSuccSent = Date(timeIntervalSinceReferenceDate: -123456789.0)
|
|
|
print("ON")
|
|
|
locationManager?.startUpdatingLocation()
|
|
|
pauseSwitch.isEnabled = true
|
|
@@ -126,6 +182,7 @@ class ViewController: UIViewController {
|
|
|
noOfSentToServer = 0
|
|
|
noOfRxGPSPos.text = String(noOfSentPos)
|
|
|
noOfSentGPSToServer.text = String(noOfSentToServer)
|
|
|
+ latestTSSent.text = "-"
|
|
|
setupTimer()
|
|
|
default:
|
|
|
print("OFF")
|
|
@@ -139,44 +196,28 @@ class ViewController: UIViewController {
|
|
|
}
|
|
|
|
|
|
extension ViewController: CLLocationManagerDelegate {
|
|
|
- // handle delegate methods of location manager here
|
|
|
- func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
|
|
|
- print("location manager authorization status changed")
|
|
|
-
|
|
|
- switch status {
|
|
|
- case .authorizedAlways:
|
|
|
- print("user allow app to get location data when app is active or in background")
|
|
|
- case .authorizedWhenInUse:
|
|
|
- print("user allow app to get location data only when app is active")
|
|
|
- case .denied:
|
|
|
- print("user tap 'disallow' on the permission dialog, cant get location data")
|
|
|
- case .restricted:
|
|
|
- print("parental control setting disallow location data")
|
|
|
- case .notDetermined:
|
|
|
- print("the location permission dialog haven't shown before, user haven't tap allow/disallow")
|
|
|
- }
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
// Step 7: Handle the location information
|
|
|
+ // This function is called when there is a new location available
|
|
|
+ // The data is put into the core data DB
|
|
|
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
|
|
|
|
|
|
- print("LocationManager didUpdateLocations: numberOfLocation: \(locations.count)")
|
|
|
+ print("Got a new position: numberOfLocations received: \(locations.count)")
|
|
|
let dateFormatter = DateFormatter()
|
|
|
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
|
|
|
|
|
|
+
|
|
|
+
|
|
|
noOfSentPos += 1
|
|
|
noOfRxGPSPos.text = String(noOfSentPos)
|
|
|
|
|
|
- //placeOrder(didUpdateLocations: locations)
|
|
|
-
|
|
|
let managedContext = appDelegate.persistentContainer.viewContext
|
|
|
let entity = NSEntityDescription.entity(forEntityName: "GPS", in: managedContext)!
|
|
|
|
|
|
// Loop through all GPS Positions and send them to the Database
|
|
|
locations.forEach { (location) in
|
|
|
- //print("LocationManager didUpdateLocations: \(dateFormatter.string(from: location.timestamp)); \(location.coordinate.latitude), \(location.coordinate.longitude)")
|
|
|
- print("LocationManager horizontalAccuracy: \(location.horizontalAccuracy)")
|
|
|
- //print("LocationManager verticalAccuracy: \(location.verticalAccuracy)")
|
|
|
+ //print("LocationManager horizontalAccuracy: \(location.horizontalAccuracy)")
|
|
|
|
|
|
let pos = NSManagedObject(entity: entity,insertInto: managedContext)
|
|
|
pos.setValue(location.coordinate.longitude, forKey: "longitud")
|
|
@@ -184,7 +225,6 @@ extension ViewController: CLLocationManagerDelegate {
|
|
|
pos.setValue(location.timestamp, forKey: "ts")
|
|
|
do {
|
|
|
try managedContext.save()
|
|
|
- //people.append(person)
|
|
|
} catch let error as NSError {
|
|
|
print("Could not save. \(error), \(error.userInfo)")
|
|
|
}
|
|
@@ -200,5 +240,35 @@ extension ViewController: CLLocationManagerDelegate {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
|
|
|
+ print("location manager authorization status changed")
|
|
|
+
|
|
|
+ switch status {
|
|
|
+ case .authorizedAlways:
|
|
|
+ print("user allow app to get location data when app is active or in background")
|
|
|
+ case .authorizedWhenInUse:
|
|
|
+ print("user allow app to get location data only when app is active")
|
|
|
+ case .denied:
|
|
|
+ print("user tap 'disallow' on the permission dialog, cant get location data")
|
|
|
+ case .restricted:
|
|
|
+ print("parental control setting disallow location data")
|
|
|
+ case .notDetermined:
|
|
|
+ print("the location permission dialog haven't shown before, user haven't tap allow/disallow")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func convertStartDate(StartDate: Date) -> String {
|
|
|
+
|
|
|
+ let dateFormatter = DateFormatter()
|
|
|
+ dateFormatter.timeZone = TimeZone.current
|
|
|
+ dateFormatter.dateFormat = "yyy-MM-dd' 'HH:mm:ss"
|
|
|
+ let dateString = dateFormatter.string(from: StartDate)
|
|
|
+ //dateFormatter.dateFormat = "yyy-MM-dd HH:mm:ss +0000"
|
|
|
+ //let date = dateFormatter.date(from: dateString)
|
|
|
+ return dateString
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|