可编码:手动处理一个密钥



我从API获得JSON,大多数密钥都是开箱即用解码的。

API响应示例:

[
{ "href":"http://audiomachine.com/",
"description":"Audiomachine",
"extended":"Music for videos",
"shared":"yes",
"toread":"no",
"tags":"creative video music"
},
{ "href": "https://www.root.cz/clanky/nekricte-na-disky-zvuk-i-ultrazvuk-je-muze-poskodit-nebo-zmast-cidla/",
"description":"Neku0159iu010dte na disky: zvuk iu00a0ultrazvuk je mu016fu017ee pou0161kodit nebo zmu00e1st u010didla - Root.cz",
"extended":"Added by Chrome Pinboard Extension",
"shared":"yes",
"toread":"no",
"tags":"root.cz ril hardware webdev"
},
{ "href": "https://www.premiumbeat.com/blog/10-apple-motion-tutorials-every-motion-designer-watch/",
"description":"10 Apple Motion Tutorials Every Motion Designer Should Watch",
"extended":"For people used to working with FCPX, sometimes learning Apple Motion can be much easier than learning After Effects. While the two programs are different, thereu2019s certainly a lot of overlap in terms of functionality and creative potential. The following ten Apple Motion tutorials are great examples of just that.rnrnWhether you are someone new to Apple Motion or a seasoned veteran looking to up your skills, here are ten must watch Apple Motion tutorials.",
"shared":"yes",
"toread":"no",
"tags":"apple apple_motion video creative effects"
}
]

我将每个项存储在下面的结构中。

struct Link: Codable {
let href: URL
let description: String
var tags: String
}

然后用之类的东西解码

URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
guard let data = data, error == nil else { return }
do {
let decoder = JSONDecoder()
let decodedData = try decoder.decode([Link].self, from: data)

根据API数据,我使用href描述标记Tags有点麻烦,因为我想在代码中使用它作为字符串数组,但在JSON中,它被检索为包含所有用空格分隔的标签的字符串。由于这是我的第一个项目,我经常学习iOS开发,我几乎不知道如何解决这个问题。

我能够通过谷歌搜索计算属性来接近它,所以它可能是类似的东西

struct Link: Codable {
let href: URL
let description: String
var tags: String {
return tagsFromServer.components(separatedBy: " ")
}
}

,但我对这个解决方案有两个问题。

  1. 我有强烈的感觉,每次代码访问.tags时都会调用这个闭包。我宁愿在JSON检索时做一次,然后再阅读它的产品
  2. 我完全不知道如何将"我从服务器获得的原始标记"/tagsFromServer传递到闭包

如果能填补我在术语方面的空白,或者能提供一个关于这个主题的精彩视频教程,我将不胜感激。

我建议编写一个自定义初始化程序,将tags解码为String并将其拆分:

struct Link: Decodable {
let href: URL
let description: String
let tags: [String]
private enum CodingKeys: String, CodingKey { case href, description, tags }
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
href = try container(URL.self, forKey: .href)
description = try container(String, forKey: .description)
let tagsFromServer = try container(String.self, forKey: .tags)
tags = tagsFromServer.components(separatedBy: " ")
}  
}

或者,您可以使用计算的属性,但必须添加CodingKeys

struct Link: Decodable {
let href: URL
let description: String
let tagsFromServer : String
private enum CodingKeys: String, CodingKey { case href, description, tagsFromServer = "tags" }
var tags: [String] {
return tagsFromServer.components(separatedBy: " ")
}
}

相关内容

  • 没有找到相关文章

最新更新