Swift 4 MapKit check if mark is near to my location - swift

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 }
}

Related

distance between current location and updated location

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))")
}

Swift using a variable in another function

How can I call testArray from locationManager() in callTestArray() ?
I tried outputting it but that doesn’t seem to work. I also tried to declare at the top of my class but then it’s always nil.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation:CLLocation = locations[0] as CLLocation
let rootRef = Database.database().reference()
let geoRef = GeoFire(firebaseRef: rootRef.child(“X”))
let query = geoRef.query(at: userLocation, withRadius: 1000)
query.observe(.keyEntered, with: { key, location in
self.testArray.insert(key, at: self.testArray.count)
})
}
func callTestArray() {
var testOuput = testArray[0]
}
Try this approach:
func locationManager(_ manager: String, didUpdateLocations locations: String, completion: #escaping () -> Void) {
let userLocation:CLLocation = locations[0] as CLLocation
let rootRef = Database.database().reference()
let geoRef = GeoFire(firebaseRef: rootRef.child(“X”))
let query = geoRef.query(at: userLocation, withRadius: 1000)
query.observe(.keyEntered, with: { key, location in
self.testArray.append(key)
completion()
})
}
Usage:
locationManager(XXXXXX, didUpdateLocations: YYYYYY) {
callTestArray()
}

Adding Start Button for Location Services [Swift 3.0 - Xcode]

I am trying to add a start button to start up my navigation and to find my current location, but nothing happens after my button is pressed?
Any help would be greatly appreciated!
Note: Map does load up, but the locationManager function does nothing, its just like it hasn't been pressed.
Heres my code:
import UIKit
import MapKit
import CoreLocation
class ThirdViewController: UIViewController , CLLocationManagerDelegate{
let manager = CLLocationManager()
func START(){
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[0]
let span:MKCoordinateSpan = MKCoordinateSpanMake(0.01,0.01) //shows the size of map screen
let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude,location.coordinate.longitude)
let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation, span)
map.setRegion(region, animated: true)
self.map.showsUserLocation = true
}
}
#IBAction func STARTNAV(_ sender: UIButton) {
START()
}
Use didUpdateLocations delegate method for getting current coordinates
& add Maps configuration in plist file as
//MARK: locations ...
let locationManager = CLLocationManager()
func start() {
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = 100.0;
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
//locationManager.requestWhenInUseAuthorization()
let authorizationStatus = CLLocationManager.authorizationStatus()
let selector = #selector(self.locationManager.requestWhenInUseAuthorization)
if self.locationManager.responds(to:selector) {
if authorizationStatus == .authorizedAlways
|| authorizationStatus == .authorizedWhenInUse {
self.locationManager.startUpdatingLocation()
}else{
self.locationManager.requestWhenInUseAuthorization()
}
}else{
self.locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print((locationManager.location?.coordinate.latitude) ?? "No values")
let status = CLAuthorizationStatus.self
print("status-------->\(status)")
let locationValue : CLLocationCoordinate2D = (manager.location?.coordinate)!
let location = CLLocation(latitude: locationValue.latitude, longitude: locationValue.longitude)
CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in
if error != nil{
print("Reverse geocoder failed with error" + error!.localizedDescription)
return
}
if placemarks!.count > 0 {
let pm = placemarks![0]
if let locationName = pm.addressDictionary!["SubLocality"] as? NSString {
print("locationName is \(locationName)")
}
}
else{
print("Problem with the data received from geocoder")
}
})
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("locationManager-failed")
}

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)

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
//
}
}