Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用一个可解码结构使用Swift解析多个JSON文件_Json_Swift_Decodable - Fatal编程技术网

使用一个可解码结构使用Swift解析多个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:

我有几个JSON提要,在这个示例中,让我们看看这两个(&)。两者都有不同的结构,但都有一系列的结构来识别我想要解析的元素,自行车站

我希望避免为我必须解析的每个JSON提要创建不同的类,如果可能的话,用相同的
可解码的
结构
解析底层结构数组。我的模型定义如下:

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中的String
    id
    和Int
    uid
    ),因此需要映射
  • 不,我不这么认为,因为您仍然需要执行
    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)}
    }