英文:
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"
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论