2016-12-30 4 views
0

Я хочу сохранить координаты местоположения в Core Data - какой правильный способ их сохранить и получить?Сохранение координаты местоположения для данных Core - Swift 3

На данный момент я делаю это и получаю ошибки:

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

Я получаю мои координаты с помощью Google Maps API с помощью автозаполнения виджета.

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 

Тогда хранить координаты, которые я использую:

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

И у меня есть все атрибуты, установленные как типы String. Затем, чтобы получить в моем ViewDidLoad у меня есть:

 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 
       } 

Так что это не работает и производит ошибку «атрибута: свойство =„координата“; желаемый тип = NSString; данный тип = NSConcreteValue '. У меня есть несколько вопросов.

Как сохранить данные координат соответствующим образом? Сохранять ли его как CLLocationDegrees или CLLocationCoordinate2D? Как преобразовать эти объекты в NSString или использовать в моих атрибутах другой тип? (Я попытался изменить его на Double или Integer, но он также вызвал ошибки). У меня есть несколько координат местоположения, которые я хотел бы хранить и извлекать из основных данных.

ответ

0

Если вы собираетесь иметь дело с большим количеством данных, то CoreData - лучший выбор.

Это мои атрибуты в объекте StorePlace, лучше всего сохранить только широту и долготу и создать координаты из них, когда это необходимо в вашей реализации.

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

И вставить новые данные, я буду делать

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

После извлечения широты, долготы можно использовать координаты в ваших реализациях, как

let newItem = getCoordinateFromCoreData() // your retrieval function 
let coordinate = CLLocationCoordinate2D(latitude: newItem.latitude, longitude: newItem.longitude) 
+0

Спасибо за это. Я получаю сообщение об ошибке, что «Appdelegate не имеет члена managedObjectContext» - есть ли что-то еще, что я должен добавить? (я использую Swift 3 и последнюю версию Xcode, они сильно изменили шаблон CoreData, если я понимаю из предыдущих версий ...) –

+0

Если целью развертывания является iOS 10, вы должны использовать appDelegate.persistentContainer.viewContext – Matt

+0

Итак, я «Пробовал это, и он все еще имеет те же ошибки. Он сбрасывается, как только я устанавливаю атрибуты Double. Я не уверен, почему он не работает. Тем временем я работал над этим, сохраняя Long и Lat как строки, и, похоже, он отлично хранит в CoreData.Теперь я пытаюсь выяснить, как превратить строки обратно в CLLocationDegrees. Считаете ли вы, что это адекватный метод для хранения и извлечения? –

0

Вам необходимо преобразовать координату, чтобы удвоить/NSdata тип, а затем сохранить его в CoreData. Используйте NSKeyedArchiver и NSKeyedUnarchiver для хранения и извлечения значений. CoreData не может напрямую хранить объект CLLocation.

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

В этом случае вам потребуется преобразовать атрибут в двоичный тип в CoreData.

+0

вы, возможно, сможете поделиться пример как это делается? Я только что посмотрел, и появились только примеры objC. –

Смежные вопросы