如何从 Codable 中的数组访问容器 (Swift)
How to access an container from an array in Decodable (Swift)
我已经尝试了一段时间,但找不到解决此问题的方法:
我从 Google 书籍 API 中得到以下示例响应:
let json = """
{
"items": [
{
"volumeInfo": {
"title": "Harry Potter und der Stein der Weisen",
"description": "Eigentlich hatte Harry geglaubt, er sei ein ganz normaler Junge. Zumindest bis zu seinem elften Geburtstag. Da erfährt er, dass er sich an der Schule für Hexerei und Zauberei einfinden soll. Und warum? Weil Harry ein Zauberer ist. Und so wird für Harry das erste Jahr in der Schule das spannendste, aufregendste und lustigste in seinem Leben. Er stürzt von einem Abenteuer in die nächste ungeheuerliche Geschichte, muss gegen Bestien, Mitschüler und Fabelwesen kämpfen. Da ist es gut, dass er schon Freunde gefunden hat, die ihm im Kampf gegen die dunklen Mächte zur Seite stehen."
}
}
]
}
""".data(using: .utf8)
此回复绝不会 return 超过一项。 (指定为参数)因此可以安全地假设项目只有一个 member/the 第一个成员是正确的。
为了代表一本书,我创建了这个结构:
struct Book: Decodable {
let title: String
let description: String?
enum OuterOuterCodingKeys: CodingKey {
case items
}
enum OuterCodingKeys: CodingKey {
case volumeInfo
}
enum CodingKeys: String, CodingKey {
case title
case description
}
init(from decoder: Decoder) throws {
let outerOuterContainer = try decoder.container(keyedBy: OuterOuterCodingKeys.self)
}
}
现在这就是我的进展。我现在需要以某种方式从 volumeInfo 中提取项目,但不知道如何进入数组。
感谢您的帮助!
您的方向正确,但我们可以为您的额外 CodingKey
枚举提供更好的名称,并将它们设为私有。
import Foundation
let jsonData = """
{
"items": [
{
"volumeInfo": {
"title": "Harry Potter und der Stein der Weisen",
"description": "Eigentlich hatte Harry geglaubt, er sei ein ganz normaler Junge. Zumindest bis zu seinem elften Geburtstag. Da erfährt er, dass er sich an der Schule für Hexerei und Zauberei einfinden soll. Und warum? Weil Harry ein Zauberer ist. Und so wird für Harry das erste Jahr in der Schule das spannendste, aufregendste und lustigste in seinem Leben. Er stürzt von einem Abenteuer in die nächste ungeheuerliche Geschichte, muss gegen Bestien, Mitschüler und Fabelwesen kämpfen. Da ist es gut, dass er schon Freunde gefunden hat, die ihm im Kampf gegen die dunklen Mächte zur Seite stehen."
}
}
]
}
""".data(using: .utf8)!
struct Book: Decodable {
let title: String
let description: String?
init(from decoder: Decoder) throws {
let rootContainer = try decoder.container(keyedBy: RootContainerKeys.self)
var itemsContainer = try rootContainer.nestedUnkeyedContainer(forKey: .items)
let itemContainer = try itemsContainer.nestedContainer(keyedBy: ItemKeys.self)
let myContainer = try itemContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .volumeInfo)
self.title = try myContainer.decode(String.self, forKey: .title)
self.description = try myContainer.decodeIfPresent(String.self, forKey: .description)
}
private enum CodingKeys: String, CodingKey {
case title
case description
}
private enum RootContainerKeys: CodingKey {
case items
}
private enum ItemKeys: CodingKey {
case volumeInfo
}
}
let book = try? JSONDecoder().decode(Book.self, from: jsonData)
print(book)
我已经尝试了一段时间,但找不到解决此问题的方法:
我从 Google 书籍 API 中得到以下示例响应:
let json = """
{
"items": [
{
"volumeInfo": {
"title": "Harry Potter und der Stein der Weisen",
"description": "Eigentlich hatte Harry geglaubt, er sei ein ganz normaler Junge. Zumindest bis zu seinem elften Geburtstag. Da erfährt er, dass er sich an der Schule für Hexerei und Zauberei einfinden soll. Und warum? Weil Harry ein Zauberer ist. Und so wird für Harry das erste Jahr in der Schule das spannendste, aufregendste und lustigste in seinem Leben. Er stürzt von einem Abenteuer in die nächste ungeheuerliche Geschichte, muss gegen Bestien, Mitschüler und Fabelwesen kämpfen. Da ist es gut, dass er schon Freunde gefunden hat, die ihm im Kampf gegen die dunklen Mächte zur Seite stehen."
}
}
]
}
""".data(using: .utf8)
此回复绝不会 return 超过一项。 (指定为参数)因此可以安全地假设项目只有一个 member/the 第一个成员是正确的。
为了代表一本书,我创建了这个结构:
struct Book: Decodable {
let title: String
let description: String?
enum OuterOuterCodingKeys: CodingKey {
case items
}
enum OuterCodingKeys: CodingKey {
case volumeInfo
}
enum CodingKeys: String, CodingKey {
case title
case description
}
init(from decoder: Decoder) throws {
let outerOuterContainer = try decoder.container(keyedBy: OuterOuterCodingKeys.self)
}
}
现在这就是我的进展。我现在需要以某种方式从 volumeInfo 中提取项目,但不知道如何进入数组。
感谢您的帮助!
您的方向正确,但我们可以为您的额外 CodingKey
枚举提供更好的名称,并将它们设为私有。
import Foundation
let jsonData = """
{
"items": [
{
"volumeInfo": {
"title": "Harry Potter und der Stein der Weisen",
"description": "Eigentlich hatte Harry geglaubt, er sei ein ganz normaler Junge. Zumindest bis zu seinem elften Geburtstag. Da erfährt er, dass er sich an der Schule für Hexerei und Zauberei einfinden soll. Und warum? Weil Harry ein Zauberer ist. Und so wird für Harry das erste Jahr in der Schule das spannendste, aufregendste und lustigste in seinem Leben. Er stürzt von einem Abenteuer in die nächste ungeheuerliche Geschichte, muss gegen Bestien, Mitschüler und Fabelwesen kämpfen. Da ist es gut, dass er schon Freunde gefunden hat, die ihm im Kampf gegen die dunklen Mächte zur Seite stehen."
}
}
]
}
""".data(using: .utf8)!
struct Book: Decodable {
let title: String
let description: String?
init(from decoder: Decoder) throws {
let rootContainer = try decoder.container(keyedBy: RootContainerKeys.self)
var itemsContainer = try rootContainer.nestedUnkeyedContainer(forKey: .items)
let itemContainer = try itemsContainer.nestedContainer(keyedBy: ItemKeys.self)
let myContainer = try itemContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .volumeInfo)
self.title = try myContainer.decode(String.self, forKey: .title)
self.description = try myContainer.decodeIfPresent(String.self, forKey: .description)
}
private enum CodingKeys: String, CodingKey {
case title
case description
}
private enum RootContainerKeys: CodingKey {
case items
}
private enum ItemKeys: CodingKey {
case volumeInfo
}
}
let book = try? JSONDecoder().decode(Book.self, from: jsonData)
print(book)