distance between current location and updated location - swift

i want to get the distance between two location.
first location is my current location and the other location is the user updated location.
so, how to track user location and measure the distance between the current location and user updated location
i tried this code and the measure is not true.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let loc = locations.last else {return}
guard let startLocation = startLocation else {
self.startLocation = loc
return
}
guard let current = manager.location else { return }
let distance = current.distance(from: startLocation)
print("Distance: \((distance))")
}

Related

Swift 4 MapKit check if mark is near to my location

I want to check when my position is changing if my location is near the Mark. I have marks with unique position. If i near for example 10m from mark i want to display alert. How i can do that?
Get visible annotations.
Calculate distance between your position and the mark.
e.g.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let myLocation = locations.first else { return }
let annotationSet = mapView.annotations(in: mapView.visibleMapRect)
for annotation in annotationSet {
guard let annotation = annotation as? MKPointAnnotation else { continue }
let loc = CLLocation(latitude: annotation.coordinate.latitude,
longitude: annotation.coordinate.longitude)
let distance = myLocation.distance(from: loc)
if distance < 10.0 { Show Alert }
}
}
}
You can implement this delegate from CLLocationManager:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let myLoc:CLLocationCoordinate2D = manager.location!.coordinate
let distance : CLLocationDistance = mark1.distanceFromLocation(myLoc)
if distance < 10.0 { //Show Alert }
}

How do I append Altitude Integers

I need to display the current Altitude in a current app I am building. However, when the Altitude is determined, the label gets displayed with xxx.xxxxxxxxxxxx
It goes super far on the other side of the decimal point. I only want it to give a at most, 2 numbers on the other side of the decimal point. How is this possible?
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations [0]
self.speedLabel.text = String(location.speed)
self.altitudeLabel.text = String(location.altitude)
CLGeocoder().reverseGeocodeLocation(location) { (placemarks, error) in
if error != nil {
print(error!)
}
That is my current code.
Like I said, I only want to display the Altitude as, "XX.XX" and not XX.XXXXXXXXX
Try this:
extension Double {
func decimal(places: Int) -> Double {
let resultString = NSString(format: "%.\(places)f" as NSString, self) as String
return Double(resultString)!
}
}
self.altitudeLabel.text = location.altitude.decimal(places: 2)
Just try:
self.altitudeLabel.text = String(format: "%.2f", location.altitude)

Completion in Updating Location Manager

I'm having an issue with the Update Location Manager.
So this is what i want to do. When the user goes into the view, it asks for location permision, when the user refuses i have set up a code that i will not post here cause it works. But if he accepts i run a function that i get the latitude and longitude of his. And then i want to run a function in which i do a query to an API. The following code is what I made
var tolat: Double = 0.0
var tolon: Double = 0.0
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
getData() { result in
switch result {
case .Success: self.eventsTable.reloadData()
case .Failure(let error): break
}
}
}
func getData(completion: Resulty<Void> -> Void) {
print("the lat \(tolat) and the lon \(tolon)")
completion(.Success())
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
tolat = locValue.latitude
tolon = locValue.longitude
locationManager.stopUpdatingLocation()
}
and after the end of the view
enum Resulty<T> {
case Success(T)
case Failure(NSError)
}
So it prints 0.0 the latitude and longitude. How can i make the func getData run when the Location Latitude and Longitude actually has data???

Fetch CloudKit records from current iCloud user

I want to fetch all of the location records from a user that is currently logged in.
This creates the location record on CloudKit:
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last!
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
addCrumbPoint(center)
let locationRecord = CKRecord(recordType: "location")
locationRecord["location"] = location
let publicData = CKContainer.defaultContainer().publicCloudDatabase
publicData.saveRecord(locationRecord) { record, error in
}
}
But how would I go about pulling out the location records for only the currently logged in user?
I want to use this to create a breadcrumb of previous journeys on a map but just getting it to print a list would be a great start!
Here is my code so far:
func getLocationAsync(complete: (instance: CKRecordID?, error: NSError?) -> ()) {
let container = CKRecordID(recordName: "Location")
publicDB.fetchRecordWithID(location) { fetchedLocation, error in
if error != nil {
print(error!.localizedDescription)
complete(instance: nil, error: error)
} else {
print("fetched Location \(recordID?.recordName)")
complete(instance: recordID, error: nil)
}
}
}
If your goal is to save the breadcrumbs locations of an user and not sharing it to other users, then use the private database.
Like that you can retrieve all the location records of the user.
If you want to use the public DB, then add an entry of type CKReference to the Location record pointing to the user record. So that you can use a predicate based on the user recordID

How to store users location on CloudKit in swift?

I'm trying to store a users journey and upload it to CloudKit.
The following takes the users location whenever they move more than 5 meters and uploads as a string but I want it to be uploaded as a location list or similar so it can be pulled down later.
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
addCrumbPoint(center)
let message = "{\"lat\":\(location!.coordinate.latitude),\"lng\":\(location!.coordinate.longitude), \"alt\": \(location!.altitude)}"
let newSweet = CKRecord(recordType: "Sweet")
newSweet["content"] = message
let publicData = CKContainer.defaultContainer().publicCloudDatabase
publicData.saveRecord(newSweet, completionHandler: { (record:CKRecord?, error:NSError?) -> Void in
if error == nil {
print("woo")
}else{
print(error)
}
})
}
The documentation on using Location and CloudKit is written in Objective-C so any help would be brilliant.
CloudKit
CLLocationManager
You create a CKRecordID and a CKRecord. Then you set the last retrieved CLLocation on the CKRecord.
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last!
let id = CKRecordID(recordName: "01")
let locationRecord = CKRecord(recordType: "location", recordID: id)
locationRecord.setObject(location, forKey: "location")
// or locationRecord["location"] = location
let publicData = CKContainer.defaultContainer().publicCloudDatabase
publicData.saveRecord(locationRecord) { record, error in
//
}
}