Unable to retrieve lat and long locations in mapView using swift ios - ios

let latitude = NSUserDefaults .standardUserDefaults().valueForKey(klat) as! Double
let longitude = NSUserDefaults .standardUserDefaults().valueForKey(klong) as! Double
let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
//Second Location lat and long
let latitudeSec:CLLocationDegrees = 11.0100
let longitudeSec:CLLocationDegrees = 77.3620
let locationSec:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitudeSec, longitudeSec)
let span:MKCoordinateSpan = MKCoordinateSpanMake(1, 1)
let region:MKCoordinateRegion = MKCoordinateRegionMake(location, span)
mapView.setRegion(region, animated: true)
let myAn1 = MyAnnotation(title: "Office", coordinate: location,subtitle: "MyOffice");
I am unable to retrieve the map locations here which I have stored in the app earlier using NSUserDefaults in the keyword "klat and "klong" It shows the following error:
"Could not cast value of type '__NSCFString' (0x1604da4) to 'NSNumber' (0x971800)"

Use following code for storing the latitude and longitude
[[NSUserDefaults standardUserDefaults] setDouble:latitude forKey:klat]
[[NSUserDefaults standardUserDefaults] setDouble:longitude forKey:klong]
And for retrieving
let latitude = NSUserDefaults.standardUserDefaults().doubleForKey(klat)
let latitude = NSUserDefaults.standardUserDefaults().doubleForKey(klong)

Related

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

How to extract lat/long placemark.coordinate in Swift?

I added a location search bar to my app. The tableview controller consists of the user location lat/long as well as the destination (address the user inputs into the search bar). As far as I can tell the latitude / longitude is within the placemark.coordinate:
placemark.coordinate = CLLocationCoordinate2D(latitude: 45.253519203737767, longitude: -66.070974382763978)
I have two variables: destLat and destLong. How I can extract the latitude and longitude from placemark.coordinate and place into the two variables mentioned above?
related code:
// cache the pin
selectedPin = placemark
// clear existing pins
mapView.removeAnnotations(mapView.annotations)
let annotation = MKPointAnnotation()
annotation.coordinate = placemark.coordinate
annotation.title = placemark.name
if let city = placemark.locality,
let prov = placemark.administrativeArea {
annotation.subtitle = "\(city), \(prov)"
}
let destination = placemark.coordinate
print("Destination coordinates: \(destination)")
let name = placemark.name
print("Placemark Name: \(name!)")
mapView.addAnnotation(annotation)
let span = MKCoordinateSpanMake(0.05, 0.05)
let region = MKCoordinateRegionMake(placemark.coordinate, span)
mapView.setRegion(region, animated: true)
Console output:
Perhaps your were thinking too hard. You can assign values to these variables just like any other:
let (destLat, destLong) = (placemark.coordinate.latitude, placemark.coordinate.longitude)
If both variable you have declare is type of Double then you need to simply need to access the latitude and longitude property of CLLocationCoordinate2D.
destLat = destination.latitude
destLong = destination.longitude
If type of both var is different then simply change it to Double works for you.

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

Checking for parameters for CLLocationCoordinate2DMake

I have a mapview where I want to check if latitude og longitude values are empty/nil or not, but either the app crashes, or Xcode is complaining about optional types and what not.
This is my current code, but I want to find out what the best way to get correct format for latitude and longitude coordinates:
if let latitude = detailItem!["lat"] as? Double {
if let longitude = detailItem!["lon"] as? Double {
// Get location
let location = CLLocationCoordinate2DMake(latitude, longitude)
// Set region
let region = MKCoordinateRegionMakeWithDistance(location, 2000, 2000)
mapCell.mapView.setRegion(region, animated: false)
// Add pin to map
let marker = MKPointAnnotation()
marker.coordinate = location
marker.title = String(detailItem!["name"]!)
mapCell.mapView.addAnnotation(marker)
}
}
This crashes entries with values.

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