如何使用 Core Data (iPhone) 存储 CLLocation?
我试图保存一个位置,然后使用 Core Location、MapKit 和 Core Data 框架在地图上检索该位置。
我所做的只是创建了名为 POI 的实体,并添加了诸如纬度(双精度类型)、经度(双精度类型)等属性以及其他一些属性。
简而言之,我的应用程序用两个 NSNumber 保存 POI。 (纬度和经度)但我觉得必须有一种比这更智能的方法来存储 CLLocation。
干杯。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
你正在做的事情很好。您应该将纬度和经度保存为核心数据中的双精度值。当您需要再次获取信息时,从 Core Data 获取双精度值并使用
CLLocationCooperative2DMake
等函数构造一个CLLocationCooperative2D
结构。没有内置的方法来存储位置,因此存储纬度和经度部分就可以了。如果您没有对纬度或经度进行任何数学运算(查找边界框等),您可以将它们存储为字符串。浮点数和双精度数可能会稍微改变它们的值,从而导致比较操作失败。
What you're doing is fine. You should save the latitude and longitude as doubles in Core Data. When you need to get the information again, get the doubles back from Core Data and construct a
CLLocationCoordinate2D
struct with a function likeCLLocationCoordinate2DMake
. There's no built in way to store a location, so storing the latitude and longitude components is fine.If you're not doing any math operations on the latitude or longitude (finding bounding boxes etc) you could store them as strings. Floats and doubles can change their values slightly, making comparison operations fail.
CLLocation 实现 NSCoding 协议,因此您可以将它们作为可转换属性存储在 Core Data 中。您可以使用默认的 NSKeyedUnarchiveFromData 值转换器。
您只需将 CCLocation 对象传递给托管对象属性,它就会将其序列化为数据并将其作为 Blob 存储在 SQL 存储中。当您需要返回位置对象时,它会自动反转该过程并返回一个完全填充的 CCLocation 对象。
这可能是获得你想要的东西的最简单的方法。
CLLocation implements the NSCoding protocol so you can store them in Core Data as transformable attributes. You can use the default NSKeyedUnarchiveFromData value transformer.
You would just pass the CCLocation object to the managed object attribute and it would serialize it to data and store it as a blob in the SQL store. When you need the location object back it would automatically reverse the process and return to you a fully populated CCLocation object.
That might be the easiest way to get what you want.
存储它的“最佳”方式取决于您想要用它做什么:
如果您手动执行操作,则可以保存/恢复许多其他属性(高度、水平精度、垂直精度、时间戳)。还有一些你无法做到的(速度、航向); CLLocation 不提供合适的初始化方法,并且属性是只读的。
如果您正在录制曲目,所有额外的属性都非常有用。如果您在山区记录 POI(“我们仍然需要爬升 100 m”),则海拔高度很有用。水平/垂直精度可用于表示 POI 有多大(例如,一个城市可能具有几公里的“水平精度”并显示为一个大圆圈)。
The "best" way to store it depends on what you want to do with it:
There's a bunch of additional properties you can save/restore if you do it manually (altitude, horizontalAccuracy, verticalAccuracy, timestamp). There are some more that you can't (speed, heading); CLLocation doesn't provide a suitable init-method and the properties are readonly.
All of the extra properties are useful if you're recording a track. Altitude is useful if you're recording a POI on mountainous terrain ("we still have to climb 100 m"). horizontal/vertical accuracy might be used to represent how big the POI is (e.g. a city might have a "horizontal accuracy" of several km and be displayed as a big circle).
您只需将 Core Data 属性类型设置为
Transformable
即可非常简单地完成此操作。如果将值转换器名称留空,则默认转换器是NSKeyedArchiver
,它适用于大多数 Foundation 类型,例如 NSURL 和 CLLocation。You can do this very simply just by setting the Core Data attribute type to
Transformable
. The default transformer if you leave the Value Transformer Name blank isNSKeyedArchiver
which works with most Foundation types such as NSURL and CLLocation.您不需要使用 NSNumber 来存储纬度和经度点。您可以将 CLLocation 直接存储到核心数据中。
为每个 CLLocation 设置一个实体,无论实体使用位置点,这都将是一个太多的关系。我们将此称为 LocationPoint:
然后,您可以在 Xcode 数据模型中将 location 属性设置为可转换。就是这样!
在 Objective-c 中,您实际上仍然可以将此 LocationPoint 属性声明为 CLLocation,不会出现任何错误:
更多信息请参见此处。
You don't need to use NSNumber to store latitude and longitude points. You can store CLLocation directly to core data instead.
Set up an entity for each CLLocation, it'll be a too-many relation off whatever entity is using location points. Let's call this LocationPoint:
You then set the location property to transformable in the Xcode data model. That's it!
In Objective-c you can actually still declare this LocationPoint property as CLLocation without any errors:
More info here.