Convert String from CoreData into CLLocationDegrees/ CLLocationCoordinate2D

833 views Asked by At

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?

2

There are 2 answers

4
vaibhav On BEST ANSWER

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
0
Adrian On

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