Swift JSONDecoder Codable优化:简化字典嵌套数组的模型访问
当然有更优雅的建模方式来简化这个访问过程!而且我先提个小细节:你原结构体里的id和active类型写错啦——JSON里id是数字(8665)、active是布尔值(true),写成String会导致解码失败,得改成Int和Bool才行。
方法1:用嵌套结构体封装Links,实现类型安全访问
我们可以把links字段单独封装成一个结构体,通过自定义CodingKey来映射JSON里的"self"关键字(避免和Swift的self冲突),这样访问时不用再通过字符串键查找字典,类型更安全,代码也更清晰:
struct Author: Codable { let name: String let emailAddress: String let id: Int let displayName: String let active: Bool let type: String let links: AuthorLinks } // 专门封装Author的links结构 struct AuthorLinks: Codable { // 用selfLinks映射JSON里的"self"字段 let selfLinks: [Link] enum CodingKeys: String, CodingKey { case selfLinks = "self" } } struct Link: Codable { let href: String }
现在访问self链接的href就变成了:
let href = author.links.selfLinks.first?.href
这种方式保留了完整的links结构,如果你之后需要处理links里其他可能的字段(比如未来新增的其他链接类型),扩展性很好。
方法2:直接提取self链接的Href,一步到位访问
如果你的业务场景里只关心self链接的第一个href,甚至可以跳过links的完整结构,直接把selfHref作为Author的一个属性,通过自定义解码逻辑实现:
struct Author: Codable { let name: String let emailAddress: String let id: Int let displayName: String let active: Bool let type: String let selfHref: String? // 直接存储self链接的第一个href // 定义Author的编码键 enum CodingKeys: String, CodingKey { case name, emailAddress, id, displayName, active, type, links } // 定义links内部的编码键 enum LinksCodingKeys: String, CodingKey { case `self` // 用反引号包裹Swift关键字 } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) // 解码基础字段 name = try container.decode(String.self, forKey: .name) emailAddress = try container.decode(String.self, forKey: .emailAddress) id = try container.decode(Int.self, forKey: .id) displayName = try container.decode(String.self, forKey: .displayName) active = try container.decode(Bool.self, forKey: .active) type = try container.decode(String.self, forKey: .type) // 解析links里的self链接 let linksContainer = try container.nestedContainer(keyedBy: LinksCodingKeys.self, forKey: .links) let selfLinks = try linksContainer.decodeIfPresent([Link].self, forKey: .self) selfHref = selfLinks?.first?.href } } struct Link: Codable { let href: String }
现在你可以直接访问:
let href = author.selfHref
这种方式把最常用的字段直接提升到Author层级,访问成本最低,适合不需要完整保留links结构的场景。
内容的提问来源于stack exchange,提问作者Vibin B. Nair
相关产品推荐
相关产品推荐

