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

Kir*_*nev 3 json swift4 codable

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

序列化json时出错:keyNotFound(Sunrise_Sunset.SunPosition.Results.(CodingKeys in _B4291256871B16D8D013EC8806040532).sunrise,Swift.DecodingError.Context(codingPath:[],debugDescription:"没有与键日出相关的值(\"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()
}
}
Run Code Online (Sandbox Code Playgroud)

vad*_*ian 8

四个问题:

  1. 添加let results : ResultsSunPosition结构.
  2. 错字:private enum CodingKeys: String, CodingKey而不是enum CodingKey :String, Swift.CodingKey,注意单数/复数差异,private建议属性,但不会导致问题.
  3. 错误的类型要解码:JSONDecoder().decode(SunPosition.self, from: data)而不是JSONDecoder().decode(SunPosition.Results.self, from: data).
  4. 要得到results你必须的print(sunPosition.results).

三个音符:

  1. 删除整个扩展程序.在这种情况下,您可以免费获得初始化程序.
  2. 添加&formatted=0到URL并设置dateDecodingStrategy解码器.iso8601以获取Date对象.更改所有日期相关的属性从类型StringDate和类型dayLenghtStringTimeInterval.改变dateDecodingStrategy写作

    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .iso8601
    let sunPosition = try decoder.decode(SunPosition.self ...
    
    Run Code Online (Sandbox Code Playgroud)
  3. 我也建议处理status.在SunPosition结构中添加它

    let status : String
    
    var success : Bool { return status == "OK" }
    
    Run Code Online (Sandbox Code Playgroud)