使用一个可解码结构使用Swift解析多个JSON文件
我有几个JSON提要,在这个示例中,让我们看看这两个(&)。两者都有不同的结构,但都有一系列的结构来识别我想要解析的元素,自行车站 我希望避免为我必须解析的每个JSON提要创建不同的类,如果可能的话,用相同的使用一个可解码结构使用Swift解析多个JSON文件,json,swift,decodable,Json,Swift,Decodable,我有几个JSON提要,在这个示例中,让我们看看这两个(&)。两者都有不同的结构,但都有一系列的结构来识别我想要解析的元素,自行车站 我希望避免为我必须解析的每个JSON提要创建不同的类,如果可能的话,用相同的可解码的结构解析底层结构数组。我的模型定义如下: struct Places: Decodable { var name: String let lat: Double let lng: Double let id: String let bikes:
可解码的结构解析底层结构数组。我的模型定义如下:
struct Places: Decodable {
var name: String
let lat: Double
let lng: Double
let id: String
let bikes: Int
enum CodingKeys: String, CodingKey {
case name
case lat = "latitude"
case lng = "longitude"
case id
case bikes = "free_bikes"
}
}
这个模型只适用于一个JSON提要,对于每个提要,我必须创建不同的编码键。这也是一个问题,因为不同的进料的中间元素不同
我目前在每个提要上使用的是不同的解析器。我的应用程序使用位置数组
在地图上添加pin,这样定义的结构
对于我解析的每个提要都是相同的。对于我来说,这不是一个可扩展的解决方案,我想问一下以下是否正确
我可以只拥有一个满足我所有需求的解析器吗
我可以只使用一个具有不同根元素的解析器,并在最后使用相同的位置结构吗
我能否构建一个解析器,只访问Places
结构中定义的中间元素,并“忘记”提要之间的顶级差异
我问了一个类似的问题,只针对内部元素。虽然这仍然是事实,但我现在在解析所有文档时遇到问题,只是为了从顶部获得位置的数组,我建议将位置
结构重命名为位置
(单数)。我还建议使用纬度
和经度
的全名
关于具体问题:
我认为1
和2
是可能的,但最终可能会得到更少的可维护代码
对。根据上面的警告是可行的
对。具有挑战性,因为在您提供的NextBike和CitiBike示例中,id的类型不同(CitiBike中的Stringid
和Intuid
),因此需要映射
不,我不这么认为,因为您仍然需要执行2
中提到的类型映射
对于可维护性,我建议为每种类型的提要创建可解码的
结构/类,并(可能)嵌入结构/类以支持层次结构,然后提供到[Place]
的映射。您可以使用协议强制执行法规遵从性
协议位置提供{
变量位置:[Place]{get}
}
结构位置:可解码{
变量名称:String
纬度:双倍
经度:双倍
let id:String
让自行车:Int
使用NextBike和CitiBike示例,您可能希望能够执行以下操作:
let decoder=JSONDecoder()
让nyc=decoder.decode(NYCitiBike.self,from:citiBikeNYC)
让nb=decoder.decode(NextBike.self,from:NextBike)
变量位置=[Place]()
places.append(内容:nb.places)
places.append(内容:nyc.places)
打印(places.count)
下面是示例Decodable
place,提供了支持此功能的
对象。这些对象的结构非常清楚相关提要的预期结构,并便于从提要中显示其他属性。这提高了可维护性,尤其是从长期来看
struct NYCitiBike:可解码,位置提供{
结构网络:可解码{
出租车站:[车站]
}
结构站:可解码{
变量名称:String
纬度:双倍
经度:双倍
let id:String
让自行车:Int
枚举编码键:字符串,编码键{
案例名称
案例纬度
经度
病例id
case bikes=“免费自行车”
}
}
让网络:网络
var站:[站]{return network.stations}
变量位置:[位置]{
stations.map{地点(名称:$0.name,纬度:$0.lation,经度:$0.lation,id:$0.id,自行车:$0.bikes)}
}
struct NextBike:Decodable,places提供{
结构国家:可解码{
let name:String
让城市:[城市]
}
结构城市:可解码{
let name:String
出租地点:[车站]
}
结构站:可解码{
let name:String
让拉特:加倍
让我们看一看:加倍
让uid:Int
让自行车:Int
}
让国家:[国家]
var站:[站]{
返回国
.flatMap{$0.5个城市}
.flatMap{$0.places}
}
变量位置:[位置]{
stations.map{地点(名称:$0.name,纬度:$0.lat,经度:$0.lng,id:String($0.uid),自行车:$0.bikes)}
}