0
I am trying to calculate the distance I travel between my starting point, until the moment I stop my race/change screen. Can you help me? The most relevant parts of the code are listed below.
@IBOutlet weak var mapa: MKMapView!
var gerenciadorLocalizacao = CLLocationManager()
@IBOutlet weak var velocidadeLabel: UILabel!
@IBOutlet weak var enderecoLabel: UILabel!
@IBOutlet weak var tempoLabel: UILabel!
@IBOutlet weak var distanciaLabel: UILabel!
@IBOutlet weak var caloriasLabel: UILabel!
lazy var timer = Timer()
var segundos = 0.0
var distancia = 0.0
var calorias = 0.0
override func viewDidLoad() {
super.viewDidLoad()
gerenciadorLocalizacao.delegate = self
gerenciadorLocalizacao.desiredAccuracy = kCLLocationAccuracyBest
gerenciadorLocalizacao.requestWhenInUseAuthorization()
gerenciadorLocalizacao.startUpdatingLocation()
timer = Timer.scheduledTimer(timeInterval: 1,
target: self,
selector: #selector(self.atualizaSegundo(timer:)),
userInfo: nil,
repeats: true)
}
func atualizaSegundo(timer: Timer) {
segundos += 1
let quantidadeSegundos = HKQuantity(unit: HKUnit.second(), doubleValue: segundos)
tempoLabel.text = quantidadeSegundos.description
let quantidadeDistancia = HKQuantity(unit: HKUnit.meter(), doubleValue: distancia)
distanciaLabel.text = quantidadeDistancia.description
let quantidadeCalorias = HKQuantity(unit:HKUnit.kilocalorie(), doubleValue: calorias)
caloriasLabel.text = quantidadeCalorias.description
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let localizacaoUsuario = locations.last!
let longitude = localizacaoUsuario.coordinate.longitude
let latitude = localizacaoUsuario.coordinate.latitude
if localizacaoUsuario.speed > 0 {
velocidadeLabel.text = String( localizacaoUsuario.speed )
}
let deltaLat: CLLocationDegrees = 0.01
let deltaLon: CLLocationDegrees = 0.01
let localizacao: CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
let areaExibicao: MKCoordinateSpan = MKCoordinateSpanMake(deltaLat, deltaLon)
let regiao: MKCoordinateRegion = MKCoordinateRegionMake(localizacao, areaExibicao)
mapa.setRegion(regiao, animated: true)
CLGeocoder().reverseGeocodeLocation( localizacaoUsuario) { (detalhesLocal, erro) in
if erro == nil {
if let dadosLocal = detalhesLocal?.first {
var thoroughfare = ""
if dadosLocal.thoroughfare != nil {
thoroughfare = dadosLocal.thoroughfare!
}
var subThoroughfare = ""
if dadosLocal.subThoroughfare != nil {
subThoroughfare = dadosLocal.subThoroughfare!
}
var locality = ""
if dadosLocal.locality != nil {
locality = dadosLocal.locality!
}
var subLocality = ""
if dadosLocal.subLocality != nil {
subLocality = dadosLocal.subLocality!
}
var postalCode = ""
if dadosLocal.postalCode != nil {
postalCode = dadosLocal.postalCode!
}
var country = ""
if dadosLocal.country != nil {
country = dadosLocal.country!
}
var administrativeArea = ""
if dadosLocal.administrativeArea != nil {
administrativeArea = dadosLocal.administrativeArea!
}
var subAdministrativeArea = ""
if dadosLocal.subAdministrativeArea != nil {
subAdministrativeArea = dadosLocal.subAdministrativeArea!
}
self.enderecoLabel.text = thoroughfare + " - "
+ subThoroughfare + " / "
+ locality + " / "
+ country
print(
"\n / Endereço:" + thoroughfare +
"\n / Número Aprox:" + subThoroughfare +
"\n / Estado:" + locality +
"\n / Bairro:" + subLocality +
"\n / CEP:" + postalCode +
"\n / País:" + country +
"\n / Estado:" + administrativeArea +
"\n / Região:" + subAdministrativeArea
)
}
}else{
print(erro)
}
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status != .authorizedWhenInUse {
let alertaController = UIAlertController(title: "Permissão de localização",
message: "Precisamos ter acesso a sua localização, por favor habilite o GPS",
preferredStyle: .alert )
let acaoConfiguracoes = UIAlertAction(title: "Configurações", style: .default , handler: { (alertaConfiguracoes) in
if let configuracoes = NSURL(string: UIApplicationOpenSettingsURLString ) {
UIApplication.shared.open( configuracoes as URL )
}
})
let acaoCancelar = UIAlertAction(title: "Cancelar", style: .default , handler: nil )
alertaController.addAction( acaoConfiguracoes )
alertaController.addAction( acaoCancelar )
present( alertaController , animated: true, completion: nil )
}
}
Do not use timers to calculate time. The correct is to store the start date
let startDate = Date()
and use instance PropertytimeIntervalSinceNow
of its DatestartDate.timeIntervalSinceNow
The result to be passed will always be negative. A solution is to use the timeIntervalSince(date:) method as followsvar segundos: TimeInterval { return Date().timeIntervalSince(startDate) }
– Leo Dabus