Converting CLLocationCoordinate2D to a String that can be stored - ios

I'm trying to save the coordinates of a user while in one ViewController so that it can be used to create an Annotation that can displayed in another ViewController.
In the view controller that stores the coordinates I'm using the code
NSUserDefaults.standardUserDefaults().setObject( Location, forKey: "Location")
In the map view controller that displays the annotation I'm trying to get the coordinates using the code
let Location = NSUserDefaults.standardUserDefaults().stringForKey("Location")
var Annotation = MKPointAnnotation()
Annotation.coordinate = Location
It is telling me that the value of type String? to a value of type CLLocationCoordinate2D.
So how do I convert the CLLocationCoordinate2D coordinates into a value of type String?

This way you can store Locations to NSUserDefaults:
//First Convert it to NSNumber.
let lat : NSNumber = NSNumber(double: Location.latitude)
let lng : NSNumber = NSNumber(double: Location.longitude)
//Store it into Dictionary
let locationDict = ["lat": lat, "lng": lng]
//Store that Dictionary into NSUserDefaults
NSUserDefaults.standardUserDefaults().setObject(locationDict, forKey: "Location")
After that you can access it this way:
//Access that stored Values
let userLoc = NSUserDefaults.standardUserDefaults().objectForKey("Location") as! [String : NSNumber]
//Get user location from that Dictionary
let userLat = userLoc["lat"]
let userLng = userLoc["lng"]
var Annotation = MKPointAnnotation()
Annotation.coordinate.latitude = userLat as! CLLocationDegrees //Convert NSNumber to CLLocationDegrees
Annotation.coordinate.longitude = userLng as! CLLocationDegrees //Convert NSNumber to CLLocationDegrees
UPDATE:
HERE is your Example project.

extension CLLocationCoordinate2D:Printable
{
init(coords : String)
{
var fullNameArr = split(coords) {$0 == ";"}
self.latitude = NSNumberFormatter().numberFromString(fullNameArr[0])!.doubleValue
self.longitude = (fullNameArr.count > 1) ? NSNumberFormatter().numberFromString(fullNameArr[1])!.doubleValue : 0
}
public var description : String
{
return "\(self.latitude);\(self.longitude)"
}
}
Then use as in your sample code :
var coord = CLLocationCoordinate2D(latitude: 3.2, longitude: 6.4)
NSUserDefaults.standardUserDefaults().setObject(coord.description, forKey: "Location")
var readedCoords = CLLocationCoordinate2D(coords: NSUserDefaults.standardUserDefaults().stringForKey("Location")!)

You can store the latitude or the longitude (or both in a dictionary or a tuple). The way to wrap them in String:
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
var locValue:CLLocationCoordinate2D = manager.location!.coordinate
var lat : String = locValue.latitude.description
var lng : String = locValue.longitude.description
//do whatever you want with lat and lng
}

Using an sprint kind of formatting:
func Coord2String(location : CLLocationCoordinate2D) -> String {
return String(format : "latitude : %f, longitude : %f", location.latitude, location.longitude)
}

Related

Cannot save the longitute and latitude from CLGeocoder()

I want to retrieve the longitute and latitude using an address as a string. I found this very useful post here: Convert address to coordinates swift
But when I want to save the results in a double field and return it I can't. What I have done is
func getLatitude(address:String) -> Double{
var lati = 0.0
var geocoder = CLGeocoder()
geocoder.geocodeAddressString("your address") {
placemarks, error in
let placemark = placemarks?.first
if let lat = placemark?.location?.coordinate.latitude{
lati = lat
}
}
}
return lati
}
Inside the geocoder.geocodeAddressString block the value is populated but when I try to return it always gives me 0.0 and I have tried everything. Any ideas please?
If it try to print the value inside the inner block of code it gets printed but I can never return it.
Thank you in advance for the answers.
CLLocationCoordinate2D is struct of latitude and longitude both defined as CLLocationDegrees which itself is a typealias of Double.
var latitude: Double?
var longitude: Double?
func getLocation(address: String) {
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(address) { placemarks, error in
guard let placemark = placemarks?.first else { return }
let coordinate = placemark.location?.coordinate
latitude = coordinate?.latitude
longitude = coordinate?.longitude
}
}

Access to the coordinates from an address swift

Hi how can I access to the longitude and latitude parameters outside of this block ?
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(address) { placemarks, error in
let placemark = placemarks?.first
let lat = placemark?.location?.coordinate.latitude
let lon = placemark?.location?.coordinate.longitude
print("Lat: \(lat), Lon: \(lon)")
}
I want to save this two params as Float or String in firebase. Thanks
You can create a function like this:
func getLatAndLong(address : String, competion : #escaping (CLLocationCoordinate2D?) -> ()) {
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(address) { placemarks, error in
let placemark = placemarks?.first
let lat = placemark?.location?.coordinate.latitude
let lon = placemark?.location?.coordinate.longitude
print("Lat: \(lat), Lon: \(lon)")
competion(placemark?.location?.coordinate)
}
}
and then call it as :
var location : CLLocationCoordinate2D?
getLatAndLong(address: "pass your address here") { (coordinates) in
self.location = coordinates
}
Now your location variable holds the value.
you can use it to get latitide and longitude
let latitide = location?.latitude
let longitude = location?.longitude
Option 2
You can declare a variable in class and update its you value once you get the coordinates. I would suggest using the above approach as geocoder runs asynchronously. Its better to use a completion handler to know when the geoCoder has finished executing the task and has got the location.
var latitude = 0.0 //
var longitude = 0.0
let geocoder = CLGeocoder()
geocoder.geocodeAddressString("address") { placemarks, error in
let placemark = placemarks?.first
self.latitude = placemark?.location?.coordinate.latitude ?? 0.0
self.longitude = placemark?.location?.coordinate.longitude ?? 0.0
}

How do I convert CLLocationCoordinate2D in a string value? [duplicate]

I'm trying to save the coordinates of a user while in one ViewController so that it can be used to create an Annotation that can displayed in another ViewController.
In the view controller that stores the coordinates I'm using the code
NSUserDefaults.standardUserDefaults().setObject( Location, forKey: "Location")
In the map view controller that displays the annotation I'm trying to get the coordinates using the code
let Location = NSUserDefaults.standardUserDefaults().stringForKey("Location")
var Annotation = MKPointAnnotation()
Annotation.coordinate = Location
It is telling me that the value of type String? to a value of type CLLocationCoordinate2D.
So how do I convert the CLLocationCoordinate2D coordinates into a value of type String?
This way you can store Locations to NSUserDefaults:
//First Convert it to NSNumber.
let lat : NSNumber = NSNumber(double: Location.latitude)
let lng : NSNumber = NSNumber(double: Location.longitude)
//Store it into Dictionary
let locationDict = ["lat": lat, "lng": lng]
//Store that Dictionary into NSUserDefaults
NSUserDefaults.standardUserDefaults().setObject(locationDict, forKey: "Location")
After that you can access it this way:
//Access that stored Values
let userLoc = NSUserDefaults.standardUserDefaults().objectForKey("Location") as! [String : NSNumber]
//Get user location from that Dictionary
let userLat = userLoc["lat"]
let userLng = userLoc["lng"]
var Annotation = MKPointAnnotation()
Annotation.coordinate.latitude = userLat as! CLLocationDegrees //Convert NSNumber to CLLocationDegrees
Annotation.coordinate.longitude = userLng as! CLLocationDegrees //Convert NSNumber to CLLocationDegrees
UPDATE:
HERE is your Example project.
extension CLLocationCoordinate2D:Printable
{
init(coords : String)
{
var fullNameArr = split(coords) {$0 == ";"}
self.latitude = NSNumberFormatter().numberFromString(fullNameArr[0])!.doubleValue
self.longitude = (fullNameArr.count > 1) ? NSNumberFormatter().numberFromString(fullNameArr[1])!.doubleValue : 0
}
public var description : String
{
return "\(self.latitude);\(self.longitude)"
}
}
Then use as in your sample code :
var coord = CLLocationCoordinate2D(latitude: 3.2, longitude: 6.4)
NSUserDefaults.standardUserDefaults().setObject(coord.description, forKey: "Location")
var readedCoords = CLLocationCoordinate2D(coords: NSUserDefaults.standardUserDefaults().stringForKey("Location")!)
You can store the latitude or the longitude (or both in a dictionary or a tuple). The way to wrap them in String:
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
var locValue:CLLocationCoordinate2D = manager.location!.coordinate
var lat : String = locValue.latitude.description
var lng : String = locValue.longitude.description
//do whatever you want with lat and lng
}
Using an sprint kind of formatting:
func Coord2String(location : CLLocationCoordinate2D) -> String {
return String(format : "latitude : %f, longitude : %f", location.latitude, location.longitude)
}

Convert String from CoreData into CLLocationDegrees/ CLLocationCoordinate2D

I had been struggling to store CLLocationCoordinate2D data from markers on a google maps to CoreData. This cannot be done directly but I found a work around where I take the coordinates, split into CLLocationDegrees, convert it into a string text and store it. I do this by the following:
let marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(place.coordinate.latitude, place.coordinate.longitude)
let newPlaceLatitude = place.coordinate.latitude
print(newPlaceLatitude)
var latitudeText:String = "\(newPlaceLatitude)"
self.latitudeText = "\(newPlaceLatitude)"
let newPlaceLongitude = place.coordinate.longitude
print(newPlaceLongitude)
var longitudeText:String = "\(newPlaceLongitude)"
self.longitudeText = "\(newPlaceLongitude)"
Storing into CoreData:
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let newPlace = NSEntityDescription.insertNewObject(forEntityName:
"StoredPlace", into: context)
newPlace.setValue(latitudeText, forKeyPath: "latitude")
newPlace.setValue(longitudeText, forKeyPath: "longitude")
However now I am struggling to reconstruct the strings back into CLLocationCoordinates. How would I turn a string to a CLLocationDegree/CLLocationCoordinate2D ? This is supposedly pretty simple but I have found that the following method doesn't work:
let latitude: CLLocationDegrees = Double(latitudeText)!
let longitude: CLLocationDegrees = Double(longitudeText)!
let markers = GMSMarker()
print(latitude)
print(longitude)
markers.position = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
any other suggestions about how to change string to coordinate?
CLLocation's latitude and longitude are doubles, so with that in mind, you might consider having latitude and longitude properties that are doubles on your StoredPlace object. I called the properties coordinateX and coordinateY so it's easier to remember that they're custom coordinates, not "factory" properties.
You could create an extension in a file called StoredPlace+Extension.swift that looks like this:
import CoreData
import CoreLocation
extension StoredPlace {
func location() -> CLLocation {
let location = CLLocation(latitude: self.coordinateX, longitude: self.coordinateY)
return location
}
}
With this extension, you can then get the coordinates out of your results as follows:
for result in results {
print("coordinate = \(result.location().coordinate)")
print("latitude = \(result.location().coordinate.latitude)")
print("longitude = \(result.location().coordinate.longitude)")
}
You need to typecast your lat and long in decimal values, more preferable is double instead of float because of precision value which can drop pins at perfect locations.
Type casting in double using as keyword:
(yourCordinateString as NSString).doubleValue
casting in float values:
(yourCordinateString as NSString).floatValue

How to make value in func to global constant in Swift

How do I go about setting the long and latitude value (both which display a when app runs) to a global constant? The values are currently
String(format: "4.4f", latestLocation.coordinate.latitude)
and
String(format: "4.4f", latestLocation.coordinate.longitude)
I want to make these a global constant like userlatitude and userlongitude which can be accessed outside the function. Do I have to return someHope that makes sense.
func locationManager(manager: CLLocationManager!,
didUpdateLocations locations: [AnyObject]!)
{
var latestLocation = locations.last as! CLLocation
latitude.text = String(format: "%.4f",
latestLocation.coordinate.latitude)
longitude.text = String(format: "%.4f",
latestLocation.coordinate.longitude)
}
This way you can store Locations to NSUserDefaults:
//First Convert it to NSNumber.
let lat : NSNumber = NSNumber(double: Location.latitude)
let lng : NSNumber = NSNumber(double: Location.longitude)
//Store it into Dictionary
let locationDict = ["lat": lat, "lng": lng]
//Store that Dictionary into NSUserDefaults
NSUserDefaults.standardUserDefaults().setObject(locationDict, forKey: "Location")
After that you can access it this way anywhere you want:
//Access that stored Values
let userLoc = NSUserDefaults.standardUserDefaults().objectForKey("Location") as! [String : NSNumber]
//Get user location from that Dictionary
let userLat = userLoc["lat"]
let userLng = userLoc["lng"]
var Annotation = MKPointAnnotation()
Annotation.coordinate.latitude = userLat as! CLLocationDegrees //Convert NSNumber to CLLocationDegrees
Annotation.coordinate.longitude = userLng as! CLLocationDegrees //Convert NSNumber to CLLocationDegrees
One solution could be that you store the values as NSUserDefaults, which gives you access to the values when you need it. try this link for more information http://www.codingexplorer.com/nsuserdefaults-a-swift-introduction/
Define your Variable Below of import statement. Something Like,
import UIKit
let latitude = 4.0
// Do Stuff - This Variable access in Any class. Thanx Swift....
Another solution is put your value in .plist/NSUser Default and access in every class(Where should you wish to use) using appropriate key.

Resources