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))
答案 0 :(得分:0)
看起来您正在尝试解码DataClass
,但URL中的JSON看起来却像是Results
对象。尝试改为解码Results
对象,看看是否可以解决您的问题:
let results = try decoder.decode(Results.self, from: safeData)
然后,如果您只想获取surahs
并将其存储到self.posts
中,则可以说:
self.posts = results.data.surahs
但是,您会发现,如果仅执行上述操作,仍然会遇到错误。有时sajda
是Bool
,有时是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
。