【问题标题】:keyNotFound(CodingKeys(stringValue: "surahs", intValue: nil) json from URLkeyNotFound(CodingKeys(stringValue: "surahs", intValue: nil) 来自 URL 的 json
【发布时间】:2020-07-26 11:15:11
【问题描述】:
struct Results: Codable {
let code: Int
let status: String
let data: DataClass
}
struct DataClass: Codable {
let surahs: [Surah]
let edition: Edition
}

struct Edition: Codable {
let identifier, language, name, englishName: String
let format, type: String
}

struct Surah: Codable, Identifiable{
var id: String{
    return "\(number)"
}
let number: Int
let name, englishName, englishNameTranslation, revelationType: String
let ayahs: [Ayah]

}

struct Ayah: Codable, Identifiable{
var id: String{
    return "\(number)"
}
let number: Int
let audio: String
let audioSecondary: [String]
let text: String
let numberInSurah, juz, manzil, page: Int
let ruku, hizbQuarter: Int
let sajda: Bool
}

这是我的打击

ContentView.swift

struct ContentView: View {

@ObservedObject var networkManager = NetworkManager()

var body: some View {
    NavigationView{

        List(networkManager.posts) {surah  in
            Text(surah.name)
        }
    .navigationBarTitle("Coran")
    }
    .onAppear {
        self.networkManager.fetchData()
    }
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
    ContentView()
}
}

NetworkManager.swift

class NetworkManager : ObservableObject{

@Published var posts = [Surah]()

func fetchData() {
    if let url = URL(string: "https://api.alquran.cloud/v1/quran/ar.alafasy"){
        let session = URLSession(configuration: .default)
        let task = session.dataTask(with: url) { (data, response, error) in
            if error == nil {
                let decoder = JSONDecoder()
                if let safeData = data{
                    do{
                        let results = try decoder.decode(DataClass.self, from: safeData)
                        DispatchQueue.main.async {
                            self.posts = results.surahs
                        }

                    } catch{
                        print(error)
                    }

                }

            }
        }
        task.resume()
    }
}
}

我尝试在我的 Swift 数据中调用此 URL,但我收到错误消息,我需要同样的帮助才能找到问题。 这是错误信息

keyNotFound(CodingKeys(stringValue: "surahs", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"surahs\", intValue: nil ) (\"surahs\").", 基础错误: nil))

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    看起来您正在尝试解码 DataClass,但您 URL 中的 JSON 看起来像是 Results 对象。尝试解码 Results 对象,看看是否能解决您的问题:

    let results = try decoder.decode(Results.self, from: safeData)
    

    那么,如果你只想获取surahs并将它们存储到self.posts,你可以说:

    self.posts = results.data.surahs
    

    但是,您会注意到,如果您只执行上述操作,您仍然会遇到错误。有时sajdaBool,有时是Dictionary。因此,您需要将 Sajda 建模为其自己的结构并将 Ayah.sajda 的类型更改为该类型而不是 Bool,然后适当地处理解码:

    struct Sajda: Codable {
        let id: Int
        let recommended: Bool
        let obligatory: Bool
    }
    
    struct Ayah: Codable, Identifiable {
        var id: String {
            return "\(number)"
        }
    
        let number: Int
        let audio: String
        let audioSecondary: [String]
        let text: String
        let numberInSurah: Int
        let juz: Int
        let manzil: Int
        let page: Int
        let ruku, hizbQuarter: Int
        let sajda: Sajda?
    
        init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            number = try container.decode(Int.self, forKey: .number)
            audio = try container.decode(String.self, forKey: .audio)
            audioSecondary = try container.decode([String].self, forKey: .audioSecondary)
            text = try container.decode(String.self, forKey: .text)
            numberInSurah = try container.decode(Int.self, forKey: .numberInSurah)
            juz = try container.decode(Int.self, forKey: .juz)
            manzil = try container.decode(Int.self, forKey: .manzil)
            page = try container.decode(Int.self, forKey: .page)
            ruku = try container.decode(Int.self, forKey: .ruku)
            hizbQuarter = try container.decode(Int.self, forKey: .hizbQuarter)
    
            sajda = try? container.decodeIfPresent(Sajda.self, forKey: .sajda)
        }
    }
    

    请注意,sajda 现在是一个可选类型——我假设当 JSON 以 Bool 的形式返回该值时(看起来它只是 false 而从来没有 true),这是后端开发人员真正的意思null 表示该对象,因此我将任何 Bool 等同于表示该对象的 nil

    【讨论】:

      猜你喜欢
      • 2019-09-17
      • 1970-01-01
      • 2021-09-04
      • 2022-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多