如何在Swift中实现Gutendex API的Format类型Codable结构体?
API 对象
Gutendex 返回的 JSON 对象类型如下:
Book
{ "id": <Project Gutenberg ID 数字>, "title": <字符串>, "subjects": <字符串数组>, "authors": <Person 对象数组>, "translators": <Person 对象数组>, "bookshelves": <字符串数组>, "languages": <字符串数组>, "copyright": <布尔值或 null>, "media_type": <字符串>, "formats": <Format 对象>, "download_count": <数字> }
Format
{ <MIME类型字符串>: <URL字符串>, ... }
Person
{ "birth_year": <数字或 null>, "death_year": <数字或 null>, "name": <字符串> }
问题解决方案
在 Swift 里,Format 这种键为任意字符串(MIME类型)、值为URL字符串的结构,最直接的实现方式是用[String: URL]字典类型——因为String和URL都默认遵循Codable协议,不需要额外编写解码/编码逻辑。
如果你偏好自定义结构体封装,也可以这样实现:
struct Format: Codable { private var storage: [String: URL] // 自定义键值对访问方式 subscript(key: String) -> URL? { get { storage[key] } set { storage[key] = newValue } } // 委托字典处理编解码逻辑 init(from decoder: Decoder) throws { storage = try [String: URL](from: decoder) } func encode(to encoder: Encoder) throws { try storage.encode(to: encoder) } }
不过大多数场景下,直接在Book结构体里把formats声明为[String: URL]就足够用,示例如下:
struct Person: Codable { let birthYear: Int? let deathYear: Int? let name: String enum CodingKeys: String, CodingKey { case birthYear = "birth_year" case deathYear = "death_year" case name } } struct Book: Codable { let id: Int let title: String let subjects: [String] let authors: [Person] let translators: [Person] let bookshelves: [String] let languages: [String] let copyright: Bool? let mediaType: String let formats: [String: URL] let downloadCount: Int enum CodingKeys: String, CodingKey { case id, title, subjects, authors, translators, bookshelves, languages, copyright case mediaType = "media_type" case formats case downloadCount = "download_count" } }
这样处理后,JSON中的Format对象会自动解码为[String: URL]类型,编码也能正常工作,完全满足需求。
内容的提问来源于stack exchange,提问作者Mr.Ironstone
相关产品推荐
相关产品推荐

