Swift4,JSON,keyNotFound,没有与key关联的值

时间:2017-12-01 19:21:15

标签: json swift4 codable

我需要做Sunset Sunrise App,这是我的代码。但我有这个错误:

  

序列化json时出错:keyNotFound(Sunrise_Sunset.SunPosition.Results。(_B4291256871B16D8D013EC8806040532中的CodingKeys).sunrise,Swift.DecodingError.Context(codingPath:[],debugDescription:"没有与键日出相关的值(\&# 34; sunrise \")。",underlyingError:nil))

我不明白如何解决它。也许有人有这个问题。我将不胜感激任何帮助) 这是API,我有:https://sunrise-sunset.org/api

struct SunPosition: Codable {
struct Results: Codable {
    let sunrise: String
    let sunset: String
    let solarNoon: String
    let dayLenght: String
    let civilTwilightBegin: String
    let civilTwilightEnd: String
    let nauticalTwilightBegin: String
    let nauticalTwilightEnd: String
    let astronomicalTwilightBegin: String
    let astronomicalTwilightEnd: String

    enum CodingKey:String, Swift.CodingKey {
        case sunrise = "sunrise"
        case sunset = "sunset"
        case solarNoon = "solar_noon"
        case dayLenght = "day_length"
        case civilTwilightBegin = "civil_twilight_begin"
        case civilTwilightEnd = "civil_twilight_end"
        case nauticalTwilightBegin = "nautical_twilight_begin"
        case nauticalTwilightEnd = "nautical_twilight_end"
        case astronomicalTwilightBegin = "astronomical_twilight_begin"
        case astronomicalTwilightEnd = "astronomical_twilight_end"
    }
  }
}

extension SunPosition.Results {
init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)
    sunrise = try values.decode(String.self, forKey: .sunrise)
    sunset = try values.decode(String.self, forKey: .sunset)
    solarNoon = try values.decode(String.self, forKey: .solarNoon)
    dayLenght = try values.decode(String.self, forKey: .dayLenght)
    civilTwilightBegin = try values.decode(String.self, forKey: .civilTwilightBegin)
    civilTwilightEnd = try values.decode(String.self, forKey: .civilTwilightEnd)
    nauticalTwilightBegin = try values.decode(String.self, forKey: .nauticalTwilightBegin)
    nauticalTwilightEnd = try values.decode(String.self, forKey: .nauticalTwilightEnd)
    astronomicalTwilightBegin = try values.decode(String.self, forKey: .astronomicalTwilightBegin)
    astronomicalTwilightEnd = try values.decode(String.self, forKey: .astronomicalTwilightEnd)
}
}

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    let jsonUrlString = "https://api.sunrise-sunset.org/json?lat=36.7201600&lng=-4.4203400"
    guard let url = URL(string: jsonUrlString) else { return }

    URLSession.shared.dataTask(with: url) { (data, response, error) in

        guard let data = data else { return }

        do {
            let sunPosition = try JSONDecoder().decode(SunPosition.Results.self, from: data)
            print(sunPosition)
        }catch let jsonErr {
            print("Error serializing json:", jsonErr)
        }

    }.resume()
}
}

2 个答案:

答案 0 :(得分:8)

四个问题:

  1. SunPosition结构中添加private enum CodingKeys: String, CodingKey
  2. 错字:enum CodingKey :String, Swift.CodingKey而不是private,请注意单数/复数差异,建议使用JSONDecoder().decode(SunPosition.self, from: data)属性但不会导致问题。
  3. 要解码的错误类型:JSONDecoder().decode(SunPosition.Results.self, from: data)而不是results
  4. 要获得print(sunPosition.results),您必须&formatted=0
  5. 三个注释:

    1. 删除整个扩展程序。在这种情况下,您可以免费获得初始化程序。
    2. dateDecodingStrategy添加到网址,并将解码器的.iso8601设置为Date以获取String个对象。将所有与日期相关的属性的类型从Date更改为dayLenght,将String的类型从TimeInterval更改为dateDecodingStrategy。要更改let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 let sunPosition = try decoder.decode(SunPosition.self ...

      status
    3. 我也建议处理SunPosition。在let status : String var success : Bool { return status == "OK" } struct

      中添加它
      {{1}}

答案 1 :(得分:1)

要排除该错误,如果您的端点由于某种原因返回了错误消息或nil数据,则会收到此错误。