Created
November 23, 2020 16:26
-
-
Save Hadevs/604fc56db3249ed18d9272352b34de4f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import CoreLocation | |
class LocationProvider: NSObject, CLLocationManagerDelegate { | |
static let shared = LocationProvider() | |
var city: String? | |
var currentLocation: CLLocation? | |
var lastRealOneLocation: CLLocation? | |
private var locationList: [CLLocation] = [] | |
private let locationManager = CLLocationManager() | |
var subscribe: ((CLLocation) -> Void)? | |
private(set) var distance: Measurement<UnitLength> = .init(value: 0, unit: .meters) | |
func requestPermissions() { | |
locationManager.allowsBackgroundLocationUpdates = true | |
locationManager.showsBackgroundLocationIndicator = true | |
locationManager.delegate = self | |
locationManager.activityType = .fitness | |
locationManager.desiredAccuracy = kCLLocationAccuracyBest | |
locationManager.requestAlwaysAuthorization() | |
locationManager.requestWhenInUseAuthorization() | |
locationManager.requestLocation() | |
} | |
func resetDistance() { | |
distance = .init(value: 0, unit: .meters) | |
} | |
func startFetchingLocation() { | |
locationManager.startUpdatingLocation() | |
} | |
func forceRequestSubcribe() { | |
guard let myLocation = currentLocation else { | |
return | |
} | |
subscribe?(myLocation) | |
} | |
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { | |
} | |
var lastLocationDate: Date? | |
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { | |
guard let location = locations.first else { | |
return | |
} | |
self.lastRealOneLocation = location | |
let speed = location.speed * 3.6 // km/h | |
let time = Date().timeIntervalSince(lastLocationDate ?? Date()) / 60 / 60 // h | |
let maxDistance = time * speed // km | |
let newLocation = locations.sorted { | |
$0.horizontalAccuracy < $1.horizontalAccuracy | |
}.first! | |
if let lastLocation = locationList.last { | |
let delta = newLocation.distance(from: lastLocation) | |
let newDistance = Measurement(value: delta, unit: UnitLength.meters) | |
// UIApplication.shared.keyWindow?.makeToast("\(maxDistance), \(newDistance.value / 1000)") | |
let coeff: Double = 0.75 | |
if (newDistance.value / 1000) * coeff > maxDistance { | |
// new Distance should not be over than maxDistance | |
return | |
} | |
distance = distance + newDistance | |
} | |
locationList.append(newLocation) | |
subscribe?(location) | |
self.currentLocation = location | |
self.lastLocationDate = Date() | |
let geocoder = CLGeocoder() | |
geocoder.reverseGeocodeLocation(location) { (placemarks, error) in | |
if let placemark = placemarks?.first { | |
self.city = placemark.locality | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment