2016-12-30 118 views
0

我想将位置坐标保存到核心数据中 - 存储这些坐标并找回它们的正确方法是什么?将位置坐标保存到核心数据 - Swift 3

目前我在做这一点,得到错误:

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

让我的坐标,从使用自动完成构件使用谷歌地图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") 

我都设置为字符串类型的属性。 然后在我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

您需要将坐标转换为double/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 

在这种情况下,您需要将Core属性转换为二进制类型。

+0

你也许能够共享一个例子之后这是如何完成的?我刚看过,只有objC的例子出现了。 –