我使用的是Mapbox框架。我使用他们的工作室(web应用程序)创建了一些地图形状(多边形和坐标),我已经下载为GeoJSON文件。此文件与我的iOS应用程序捆绑在一起。所有提供的示例都非常小,并且有一个简单的结构,比如viewDidLoad
中的所有剩余代码。
我正在尝试设计应用程序,以便数据加载一次,然后可以访问此变量,以便根据需要添加和/或删除某些映射项。
我应该使用全局变量吗?如果是,我应该在哪里声明data
变量,以便可以在任何地方访问它?或者这是一种不好的做法,我应该将data
变量加载到一个范围访问较少的地方,然后在适当的函数调用中传递对象本身?这也不会让人困惑吗?初始负载的最佳位置在哪里?
do {
let url = URL(fileURLWithPath: Bundle.main.path(forResource: "features", ofType: "geojson")!)
let data = try Data(contentsOf: url)
} catch {
print(error)
}
然后我将有其他函数,可以过滤这个数据集,只添加或删除特定的地图对象。
func loadSomeData(forGroup name: String, withData data: Data) {
let shapeCollection = try MGLShape(data: data, encoding: String.Encoding.utf8.rawValue) as! MGLShapeCollectionFeature
for shape in shapeCollection.shapes {
if shape.attribute(forKey: "group") as! String == name {
if let point = shape as? MGLPointAnnotation {
// ADD ITEM TO MAP
} else if let polygon = shape as? MGLPolygon {
// ADD ITEM TO MAP
}
}
}
}
var group = "group1"
loadSomeData(forGroup: group)
因此,这将为具有“GROP1”属性的所有对象过滤相同的原始数据源,并且只加载这些对象(它将通过删除现有对象来进行,并且可以做很多其他事情-我只需要掌握基本知识……)
最后,我希望解析GeoJSON数据文件,并为分组项创建自定义对象。但是文件的结构是完全随机的,这意味着对象类的属性需要完全是optionals,但是从我早期的测试来看,有些是延迟加载/计算的属性,不能很好地与optionals一起工作。。。
最佳答案
听起来你有两个问题:从包中加载数据,并使其全局可访问。
如果数据永远不会改变,那么只需从包中读取就可以了。如果在应用程序的生命周期中可能发生更改,则可能需要编写在启动时运行的代码,该代码将在启动时检查文档中的文件,如果找不到该文件,则将其从捆绑包复制到文档目录,然后从文档中将其打开。
然后,您需要查询您的服务器以查看您的数据是否是最新的(使用版本号或更新时间戳)。如果数据已更改,您将下载新数据,保存对文档的更改,并更新版本/时间戳。
至于在应用程序范围内提供数据,这可能是数据容器singleton的一个很好的用例。singleton将有方法来查询您的地图数据,它将负责加载/更新上面描述的逻辑。
或者,您可以决定数据是否能够很好地映射到核心数据。
至于如何设计数据模型,这是一个单独的对话,您需要提供更多信息。