URL中的keyNotFound(CodingKeys(stringValue:“ surahs”,intValue:nil)json

时间:2020-04-13 19:51:46

标签: ios swift

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:“没有与键CodingKeys(stringValue:\” surahs \“,intValue:nil相关联的值) )(\“ surahs \”)。“,underlyingError:nil))

1 个答案:

答案 0 :(得分:0)

看起来您正在尝试解码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,而从未{{1} }),后端开发人员实际上是为该对象表示true,因此我将任何null等同为该对象的Bool

相关问题