JSONDecoder not decoding API data

huangapple go评论57阅读模式
英文:

JSONDecoder not decoding API data

问题

以下是翻译的内容:

我正在尝试通过API获取一个JSON对象,它看起来像这样:

{
    "data": [
        {
            "book_id": "MAT",
            "book_name": "Matthew",
            "book_name_alt": "Matthew",
            "chapter": 1,
            "chapter_alt": "1",
            "verse_start": 1,
            "verse_start_alt": "1",
            "verse_end": 1,
            "verse_end_alt": "1",
            "verse_text": "The book of the genealogy of Jesus Christ, the son of David, the son of Abraham."
        },
        {
            "book_id": "MAT",
            "book_name": "Matthew",
            "book_name_alt": "Matthew",
            "chapter": 1,
            "chapter_alt": "1",
            "verse_start": 2,
            "verse_start_alt": "2",
            "verse_end": 2,
            "verse_end_alt": "2",
            "verse_text": "Abraham was the father of Isaac, and Isaac the father of Jacob, and Jacob the father of Judah and his brothers,"
        }
    ]
}

我的函数成功获取数据,但是它在JSONDecoder()这一行之后无法继续执行。也许我没有正确编写结构体或.decode()?或者我需要使用`CodingKeys``unkeyedContainer`吗?出于明显的原因,我在下面删除了URL和密钥

struct Response: Codable {
    var verses: [Verse]
}

struct Verse: Codable, Identifiable {
    var id = UUID()
    var book_id: String
    var book_name: String
    var book_name_alt: String
    var chapter: Int
    var chapter_alt: String
    var verse_start: Int
    var verse_start_alt: String
    var verse_end: Int
    var verse_end_alt: String
    var verse_text: String
}

func getText() async {
    let urlString = "..."
    guard let url = URL(string: urlString) else {
        print("无效的URL")
        return
    }
    var request = URLRequest(url: url)
    request.setValue("...", forHTTPHeaderField: "key")
    request.setValue("...", forHTTPHeaderField: "v")
    
    do {
        let (data, _) = try await URLSession.shared.data(for: request)
        if let decodedResponse = try? JSONDecoder().decode(Response.self, from: data) {
            verses = decodedResponse.verses
        }
    } catch {
        print("无效的数据")
    }
}

希望这能帮助你解决问题!

英文:

I am trying to get a JSON object via API that looks like this:

{
"data": [
{
"book_id": "MAT",
"book_name": "Matthew",
"book_name_alt": "Matthew",
"chapter": 1,
"chapter_alt": "1",
"verse_start": 1,
"verse_start_alt": "1",
"verse_end": 1,
"verse_end_alt": "1",
"verse_text": "The book of the genealogy of Jesus Christ, the son of David, the son of Abraham."
},
{
"book_id": "MAT",
"book_name": "Matthew",
"book_name_alt": "Matthew",
"chapter": 1,
"chapter_alt": "1",
"verse_start": 2,
"verse_start_alt": "2",
"verse_end": 2,
"verse_end_alt": "2",
"verse_text": "Abraham was the father of Isaac, and Isaac the father of Jacob, and Jacob the father of Judah and his brothers,"
}
]
}

My function gets the data successfully, however it doesn't get progress past the JSONDecoder() line. Perhaps I haven't written the structs or .decode() correctly? Or do I have to use CodingKeys or unkeyedContainer ?I have deleted the url and key below for obvious reasons.

struct Response: Codable {
var verses: [Verse]
}
struct Verse: Codable, Identifiable {
var id = UUID()
var book_id: String
var book_name: String
var book_name_alt: String
var chapter: Int
var chapter_alt: String
var verse_start: Int
var verse_start_alt: String
var verse_end: Int
var verse_end_alt: String
var verse_text: String
}
func getText() async {
let urlString = "..."
guard let url = URL(string: urlString) else {
print("Invalid URL")
return
}
var request = URLRequest(url: url)
request.setValue("...", forHTTPHeaderField: "key")
request.setValue("...", forHTTPHeaderField: "v")
do {
let (data, _) = try await URLSession.shared.data(for: request)
if let decodedResponse = try? JSONDecoder().decode(Response.self, from: data) {
verses = decodedResponse.verses
}
} catch {
print("Invalid data")
}
}

The function should get the data, decode it into a swift struct so that I can then display the verse text in a scrollview. Thanks for the help!

答案1

得分: 1

在解码JSON数据时,你需要让模型的属性与JSON数据相匹配。你可以使用CodingKeys来更改属性的名称,例如:

struct Response: Codable {
    var verses: [Verse]
    
    enum CodingKeys: String, CodingKey {
        case verses = "data"
    }
}

struct Verse: Codable, Identifiable {
    let id = UUID()
    let chapter, verseStart, verseEnd: Int
    let bookID, bookName, bookNameAlt, chapterAlt: String
    let verseStartAlt, verseEndAlt, verseText: String

    enum CodingKeys: String, CodingKey {
        case chapter
        case bookID = "book_id"
        case bookName = "book_name"
        case bookNameAlt = "book_name_alt"
        case chapterAlt = "chapter_alt"
        case verseStart = "verse_start"
        case verseStartAlt = "verse_start_alt"
        case verseEnd = "verse_end"
        case verseEndAlt = "verse_end_alt"
        case verseText = "verse_text"
    }
}
英文:

When decoding json data, you need the models to match the json data.
You can use CodingKeys to change the names of the properties, such as:

struct Response: Codable {
var verses: [Verse]
enum CodingKeys: String, CodingKey {
case verses = "data"
}
}
struct Verse: Codable, Identifiable {
let id = UUID()
let chapter, verseStart, verseEnd: Int
let bookID, bookName, bookNameAlt, chapterAlt: String
let verseStartAlt, verseEndAlt, verseText: String
enum CodingKeys: String, CodingKey {
case chapter
case bookID = "book_id"
case bookName = "book_name"
case bookNameAlt = "book_name_alt"
case chapterAlt = "chapter_alt"
case verseStart = "verse_start"
case verseStartAlt = "verse_start_alt"
case verseEnd = "verse_end"
case verseEndAlt = "verse_end_alt"
case verseText = "verse_text"
}
}

huangapple
  • 本文由 发表于 2023年3月7日 10:18:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75657505.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定