簡體   English   中英

Swift4、JSON、keyNotFound、沒有與鍵關聯的值

[英]Swift4, JSON, keyNotFound, No value associated with key

我需要做 Sunset Sunrise App,這是我的代碼。 但我有這個錯誤:

錯誤序列化 json: keyNotFound(Sunrise_Sunset.SunPosition.Results.(CodingKeys in _B4291256871B16D8D013EC8806040532).sunrise, Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key sunrise\\").\\"底層錯誤:無))

我不明白如何解決它。 也許有人有這個問題。 如有任何幫助,我將不勝感激)這是我擁有的 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()
}
}

四個問題:

  1. 添加let results : ResultsSunPosition結構中的let results : Results
  2. private enum CodingKeys: String, CodingKeyprivate 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. 在 URL 中添加&formatted=0並將解碼器的dateDecodingStrategy設置為.iso8601以獲取Date對象。 將所有與日期相關的屬性的類型從String更改為Date ,將dayLenght的類型從String更改為TimeInterval 改變dateDecodingStrategy

    let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 let sunPosition = try decoder.decode(SunPosition.self ...
  3. 我也建議處理status 將此添加到SunPosition結構中

    let status : String var success : Bool { return status == "OK" }

為了排除它,如果由於某種原因您的端點返回錯誤消息或零數據,您將收到此錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM