解析复杂的json代码

时间:2018-04-22 15:25:36

标签: swift swift4

我有以下JSON代码,并希望在Swift中解析它。我使用Alamofire获取JSON并为解析创建了一个结构:

    {  
   "-8802586561990153106-1804221538-5":{  
      "zug":{  
         "klasse":"RB",
         "nummer":"28721"
      },
      "ankunft":{  
         "zeitGeplant":"1804221603",
         "zeitAktuell":"1804221603",
         "routeGeplant":[  
            "Wiesbaden Hbf",
            "Mainz Hbf"
         ]
      },
      "abfahrt":{  
         "zeitGeplant":"1804221604",
         "zeitAktuell":"1804221604",
         "routeGeplant":[  
            "Gro\u00df Gerau",
            "Klein Gerau",
            "Weiterstadt"
         ]
      }
   },
   "8464567322535526441-1804221546-15":{  
      "zug":{  
         "klasse":"RB",
         "nummer":"28724"
      },
      "ankunft":{  
         "zeitGeplant":"1804221657",
         "zeitAktuell":"1804221708",
         "routeGeplant":[  
            "Aschaffenburg Hbf",
            "Mainaschaff"
         ]
      },
      "abfahrt":{  
         "zeitGeplant":"1804221658",
         "zeitAktuell":"1804221709",
         "routeGeplant":[  
            "Mainz-Bischofsheim"
         ]
      }
   }
}

我为此创建了一个结构,如下所示:

struct CallResponse: Codable {
    struct DirectionTrain: Codable {
        struct Train: Codable {
            let trainClass: String
            let trainNumber: String
        }
        struct Arrival: Codable {
            let line: String
            let eta: Date
            let ata: Date
            let platform: String
            let route: [String]
        }
        struct Departure: Codable {
            let line: String
            let etd: Date
            let atd: Date
            let platform: String
            let route: [String]
        }
    }
 }

我的其余代码是:

 Alamofire.request(url!).responseJSON { response in
            switch response.result {
            case .success:
                let decoder = JSONDecoder()
                let parsedResult = try! decoder.decode(CallResponse.self, from: response.data!)
            case .failure(let error):
                print(error)
            }
        }

当我运行此代码时,错误消息为:

Thread 1: Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "train", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"train\", intValue: nil) (\"train\").", underlyingError: nil))

任何人都可以帮我找到问题吗?谢谢你的回答!

1 个答案:

答案 0 :(得分:1)

问题只是你的结构看起来像你的JSON一样!

您的JSON是一个字典,其键的名称类似于"-8802586561990153106-1804221538-5""8464567322535526441-1804221546-15"。但是我没有看到你声明任何处理这些键的结构。

然后,每一个都变成了一个包含"zug""ankunft""abfahrt"等字符的字典。但我也没有看到你声明任何处理这些键的结构。

然后"zug"有密钥"klasse""nummer";你也没有。

等等。

您的结构必须看起来与您的JSON完全相同,否则您必须定义CodingKeys并可能还实现init(from:)来处理结构和JSON之间的任何差异。我怀疑密钥"-8802586561990153106-1804221538-5""8464567322535526441-1804221546-15"是不可预测的,因此您可能会 编写init(from:)以便处理它们。

例如,我能够像这样解码你的JSON(我真的不建议使用try!,但是我们解码时没有错误而且它只是一个测试):

    struct Entry : Codable {
        let zug : Zug
        let ankunft : AnkunftAbfahrt
        let abfahrt : AnkunftAbfahrt
    }
    struct Zug : Codable {
        let klasse : String
        let nummer : String
    }
    struct AnkunftAbfahrt : Codable {
        let zeitGeplant : String
        let zeitAktuell : String
        let routeGeplant : [String]
    }
    struct Top : Decodable {
        var entries = [String:Entry]()
        init(from decoder: Decoder) throws {
            struct CK : CodingKey {
                var stringValue: String
                init?(stringValue: String) {
                    self.stringValue = stringValue
                }
                var intValue: Int?
                init?(intValue: Int) {
                    return nil
                }
            }
            let con = try! decoder.container(keyedBy: CK.self)
            for key in con.allKeys {
                self.entries[key.stringValue] = 
                    try! con.decode(Entry.self, forKey: key)
            }
        }
    }
    // d is a Data containing your JSON
    let result = try! JSONDecoder().decode(Top.self, from: d)