如何使用嵌套 json 构建结构?
How do I make a struct with nested json?
我的 api 收到 JSON 回复,returns 这个:
[
{
"id": 1,
"chapter": 5,
"amount": 28,
"texts": [
{
"lyric": "lorem ipsum",
"number": 1
},
{
"lyric": "lorem foo bar",
"number": 2
}
],
"book": 1
}
]
我试过了
struct Chapter: Decodable, Identifiable {
var id: Int
var chapter: Int
var amount: Int
struct Lyrics: Codable {
var lyricText: String
var lyricNumber: Int
}
enum Codingkeys: String, CodingKey {
case lyricText = "lyric"
case lyricNumber = "number"
}
}
但是我在拨打电话时收到以下错误
dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.})))
我的 API 调用如下所示:
...
@Published var chapters = [Chapter]()
func fetchBookDetails() {
if let url = URL(string: url) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error == nil {
if let safeData = data {
do {
let response = try JSONDecoder().decode([Chapter].self, from: safeData)
DispatchQueue.main.async {
self.chapters = response
}
} catch {
print(error)
}
}
}
}
task.resume()
}
}
我猜该结构看起来不错,但是 api 调用有问题 - 知道它可能是什么吗?还是结构做错了
texts
是一个子结构(属性数组),所以需要为它定义第二个容器,例如
struct Text: Codable {
let lyric: String
let number: Int
}
然后您可以更新 Chapter
以引用子结构,例如...
struct Chapter: Decodable {
let id: Int
let chapter: Int
let amount: Int
let book: Int
let texts: [Text]
}
最后,加载它...
let chapters = try JSONDecoder().decode([Chapter].self, from: jsonData)
But what about the error message?
dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.})))
哦,对了,但是错误消息告诉您下载的内容有问题。在这些情况下,我喜欢将数据转换为 String
并在可能的情况下打印出来,这样,您就知道返回给您的是什么。
例如:
let actualText = String(data: safeData, encoding: .utf8)
打印这个看看你实际得到了什么
游乐场测试代码
import UIKit
let jsonText = """
[
{
"id": 1,
"chapter": 5,
"amount": 28,
"texts": [
{
"lyric": "lorem ipsum",
"number": 1
},
{
"lyric": "lorem foo bar",
"number": 2
},
],
"book": 1
}
]
"""
struct Text: Codable {
let lyric: String
let number: Int
}
struct Chapter: Decodable {
let id: Int
let chapter: Int
let amount: Int
let book: Int
let texts: [Text]
}
let jsonData = jsonText.data(using: .utf8)!
do {
let chapters = try JSONDecoder().decode([Chapter].self, from: jsonData)
} catch let error {
error
}
我的 api 收到 JSON 回复,returns 这个:
[
{
"id": 1,
"chapter": 5,
"amount": 28,
"texts": [
{
"lyric": "lorem ipsum",
"number": 1
},
{
"lyric": "lorem foo bar",
"number": 2
}
],
"book": 1
}
]
我试过了
struct Chapter: Decodable, Identifiable {
var id: Int
var chapter: Int
var amount: Int
struct Lyrics: Codable {
var lyricText: String
var lyricNumber: Int
}
enum Codingkeys: String, CodingKey {
case lyricText = "lyric"
case lyricNumber = "number"
}
}
但是我在拨打电话时收到以下错误
dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.})))
我的 API 调用如下所示:
...
@Published var chapters = [Chapter]()
func fetchBookDetails() {
if let url = URL(string: url) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error == nil {
if let safeData = data {
do {
let response = try JSONDecoder().decode([Chapter].self, from: safeData)
DispatchQueue.main.async {
self.chapters = response
}
} catch {
print(error)
}
}
}
}
task.resume()
}
}
我猜该结构看起来不错,但是 api 调用有问题 - 知道它可能是什么吗?还是结构做错了
texts
是一个子结构(属性数组),所以需要为它定义第二个容器,例如
struct Text: Codable {
let lyric: String
let number: Int
}
然后您可以更新 Chapter
以引用子结构,例如...
struct Chapter: Decodable {
let id: Int
let chapter: Int
let amount: Int
let book: Int
let texts: [Text]
}
最后,加载它...
let chapters = try JSONDecoder().decode([Chapter].self, from: jsonData)
But what about the error message?
dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.})))
哦,对了,但是错误消息告诉您下载的内容有问题。在这些情况下,我喜欢将数据转换为 String
并在可能的情况下打印出来,这样,您就知道返回给您的是什么。
例如:
let actualText = String(data: safeData, encoding: .utf8)
打印这个看看你实际得到了什么
游乐场测试代码
import UIKit
let jsonText = """
[
{
"id": 1,
"chapter": 5,
"amount": 28,
"texts": [
{
"lyric": "lorem ipsum",
"number": 1
},
{
"lyric": "lorem foo bar",
"number": 2
},
],
"book": 1
}
]
"""
struct Text: Codable {
let lyric: String
let number: Int
}
struct Chapter: Decodable {
let id: Int
let chapter: Int
let amount: Int
let book: Int
let texts: [Text]
}
let jsonData = jsonText.data(using: .utf8)!
do {
let chapters = try JSONDecoder().decode([Chapter].self, from: jsonData)
} catch let error {
error
}