【问题标题】:Saving location coordinates to Core data- Swift 3将位置坐标保存到核心数据 - Swift 3
【发布时间】:2017-05-14 20:33:39
【问题描述】:

我想将位置坐标保存到核心数据中——存储和检索它们的正确方法是什么?

目前我正在这样做并遇到错误:

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

我通过 Google 地图 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
                }

所以这不起作用并产生'attribute:property =“coordinate”的错误;所需类型 = NSString;给定类型 = NSConcreteValue'。我有几个问题。

如何正确保存坐标数据? 我是否将其保存为 CLLocationDegrees 或 CLLocationCoordinate2D? 如何将这些对象转换为 NSString 或者我应该在我的属性中使用不同的类型? (我尝试将其更改为 Double 或 Integer 但它也产生了错误)。我有多个位置坐标,我想从核心数据中存储和检索。

【问题讨论】:

    标签: ios swift core-data nsstring cllocation


    【解决方案1】:

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

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

    【讨论】:

    • 您能否分享一个如何做到这一点的示例?我刚刚看了看,只有 objC 示例即将出现。
    【解决方案2】:

    如果您要处理大量数据,那么 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)
    

    【讨论】:

    • 谢谢。我收到一条错误消息,提示“Appdelegate 没有成员 managedObjectContext” - 还有其他我应该添加的内容吗? (我正在使用 Swift 3 和最新版本的 Xcode,如果我从以前的版本中理解的话,他们已经非常显着地改变了 CoreData 模板......)
    • 如果你的部署目标是 iOS 10,你应该使用 appDelegate.persistentContainer.viewContext
    • 所以我试过这个,它仍然有同样的错误。一旦我将属性设置为 Double,它就会崩溃。我不确定为什么它不起作用。与此同时,我通过将 Long 和 Lat 保存为字符串来解决这个问题,它似乎可以很好地存储到 CoreData 中。现在我正在尝试研究如何将字符串转回 CLLocationDegrees。您认为这是存储和检索的适当方法吗?
    • 如何将数据保存到坐标中并不重要。您可以将Strings转换为Double,它可以直接与CLLocationDegrees一起使用。
    • 我的意思是你如何将数据保存到 CoreData 中并不重要,如果你可以随意使用它们并且 CoreData 支持这些数据类型。
    猜你喜欢
    • 2017-07-17
    • 2017-09-20
    • 2016-08-19
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多