1

I want to save location coordinates into Core Data- what is the right way of storing these and retrieving them?

At the moment I am doing this and getting errors:

 var newPlaceCoordinate = CLLocationCoordinate2D() var newPlaceLatitude = CLLocationDegrees() var newPlaceLongitude = CLLocationDegrees() 

I get my coordinates from using Google maps API using the autocomplete widget.

 let newPlaceCoordinate = place.coordinate self.newPlaceCoordinate = place.coordinate let newPlaceLatitude = place.coordinate.latitude print(newPlaceLatitude) self.newPlaceLatitude = place.coordinate.latitude let newPlaceLongitude = place.coordinate.longitude print(newPlaceLongitude) self.newPlaceLongitude = place.coordinate.longitude 

Then to store the coordinates I use:

 let appDelegate = UIApplication.shared.delegate as! AppDelegate let context = appDelegate.persistentContainer.viewContext let newPlace = NSEntityDescription.insertNewObject(forEntityName: "StoredPlace", into: context) newPlace.setValue(newPlaceCoordinate, forKey: "coordinate") newPlace.setValue(newPlaceLatitude, forKeyPath: "latitude") newPlace.setValue(newPlaceLongitude, forKeyPath: "longitude") 

And I have the attributes all set as String types. Then to retrieve in my ViewDidLoad I have:

 let appDelegate = UIApplication.shared.delegate as! AppDelegate let context = appDelegate.persistentContainer.viewContext let request = NSFetchRequest<NSFetchRequestResult>(entityName: "StoredPlace") request.returnsObjectsAsFaults = false if let coordinate = result.value(forKey: "coordinate") as? String { let latitude = (coordinate as NSString).doubleValue let longitude = (coordinate as NSString).doubleValue let markers = GMSMarker() markers.position = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) markers.icon = GMSMarker.markerImage(with: UIColor.yellow) markers.tracksViewChanges = true markers.map = vwGMap } 

So this is not working and producing an error of 'attribute: property = "coordinate"; desired type = NSString; given type = NSConcreteValue'. I have a few questions.

How do I save a coordinate data appropriately? Do I save it as a CLLocationDegrees or CLLocationCoordinate2D? How do I convert these objects into NSString or should I be using a different type in my attributes? (I tried changing it to Double or Integer but it also produced errors). I have multiple location coordinates which I would want to store and retrieve from core data.

2 Answers 2

3

If you are going to deal with lots of data, then CoreData is the best bet.

These are my attributes in StorePlace entity, its best to save only latitude and longitude and create coordinates from them when needed in your implementation.

@NSManaged public var newPlaceLatitude: Double @NSManaged public var newPlaceLongitude: Double 

And to insert new data, I will do

class func insert(latitude: Double, longitude: Double) { let appDelegate = UIApplication.shared.delegate as! AppDelegate let managedObjectContext = appDelegate.managedObjectContext let entity = NSEntityDescription.entity(forEntityName: "StoredPlace", in:managedObjectContext) let newItem = StoredPlace(entity: entity!, insertInto: managedObjectContext) newItem.newPlaceLatitude = latitude newItem.newPlaceLongitude = longitude do { try managedObjectContext.save() } catch { print(error) } } 

After retrieving latitude, longitude you can use coordinate in your implementations as

let newItem = getCoordinateFromCoreData() // your retrieval function let coordinate = CLLocationCoordinate2D(latitude: newItem.latitude, longitude: newItem.longitude) 
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for this. I'm getting an error saying that 'Appdelegate has no member managedObjectContext' - is there something else I should be adding? (i am using Swift 3 and the latest version of Xcode they have changed the CoreData template quite dramatically if i understand from previous versions...)
If your deployment target is iOS 10, you should use appDelegate.persistentContainer.viewContext
So I've tried this and it is still having the same errors. It crashes as soon as I set the attributes to Double. I am not sure why its not working. In the meantime I have worked round this by saving the Long and Lat as strings and it seems to store fine into CoreData. Now I am trying to work out how to turn the strings back into CLLocationDegrees. Do you think this is an adequate method for storing and retrieving?
It doesn't matter how you save data into coordinates. You can convert Strings to Double, it can be used directly with CLLocationDegrees.
I meant it doesn't matter how you save your data into CoreData, if you can use them for as you wish and CoreData supports those data types.
0

You need to convert the co-ordinate to double/NSdata type and then store it in CoreData. Use NSKeyedArchiver and NSKeyedUnarchiver to store and retrieve the values. CoreData can't store CLLocation object directly.

// Convert CLLocation object to Data let newPlaceLatitudeArchived = NSKeyedArchiver.archivedDataWithRootObject(newPlaceLatitude) //CoreData Piece newPlace.setValue(newPlaceLatitudeArchived, forKeyPath: "latitude") // fetch the latitude from CoreData as Archive object and pass it to unarchive to get the CLLocation let newPlaceLatitudeUnArchived = NSKeyedUnarchiver.unarchiveObjectWithData(archivedLocation) as? CLLocation 

You will need to convert you attribute to binary type in CoreData in this case.

1 Comment

are you perhaps able to share an example of how that is done? I have just had a look and only objC examples are coming up.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.