从嵌套的 JSON 中检索数据
Posted
技术标签:
【中文标题】从嵌套的 JSON 中检索数据【英文标题】:Retrieving data from nested JSON 【发布时间】:2022-01-18 07:32:52 【问题描述】:我正在努力理解如何从我的 JSON 文件中获取数据并使用它(例如在按下按钮时,它会更改标签文本或描述),尽管我已经阅读了无数的线程,但我仍然卡住了,但这里是我从这些文章和 *** 线程中尝试做的事情。
假设我有一个名为 Animals.json 的 json 文件:
"animal": [
"name":"Cat",
"image" : "cat.jpg",
"category": "mammal"
,
"name":"Eagle",
"image" : "eagle.jpg",
"category": "Bird",
]
我在一个名为 Animals.swift 的单独文件中创建了一个结构:
struct Animals: Codable
var animal: [Animal]
然后是另一个名为 Animal.swift 的文件:
struct Animal : Codable
var name: String
var image: String
var category: String
这是我的 MainVC 中的代码:
import UIKit
class InstrumentsVC: UIViewController
override func viewDidLoad()
super.viewDidLoad()
if let localData = self.readLocalFile(forName: "Animals")
self.parse(jsonData: localData)
private func readLocalFile(forName name: String) -> Data?
do
if let bundlePath = Bundle.main.path(forResource: name,
ofType: "json"),
let jsonData = try String(contentsOfFile: bundlePath).data(using: .utf8)
return jsonData
catch
print(error)
return nil
private func parse(jsonData: Data)
do
let decodedData = try JSONDecoder().decode(Animals.self,
from: jsonData)
print("animal: ", decodedData.animal.first?.name ?? "")
catch
print("decode error")
private func loadJson(fromURLString urlString: String,
completion: @escaping (Result<Data, Error>) -> Void)
if let url = URL(string: urlString)
let urlSession = URLSession(configuration: .default).dataTask(with: url) (data, response, error) in
if let error = error
completion(.failure(error))
if let data = data
completion(.success(data))
urlSession.resume()
@IBAction func nextCategory(_ sender: UIButton)
//I'll write a function that allows changing categories then loading an image that will update an outlet and labels
我还没有开始调用 loadJson 函数的部分,因为我打印了一个解码错误,而且我是 JSON 解码/解析的新手,我想知道哪里出了问题以及如何修复那。 这个想法是当我要按下一个按钮时,它会循环遍历我的 JSON 的“类别”部分(我还没有编写函数,但这应该不是问题),然后我有另一个按钮可以通过“名称”触发循环(这是一个简化的 JSON,因为会有很多来自同一类别的元素;它也不会是动物,而是一些与音乐相关的东西,我只是认为这样更容易理解用动物而不是放一些音乐理论的东西)。
现在我被打印在 readLocalFile 函数中的错误卡住了;然后从我读过的多篇文章中,我显然需要调用 loadJson 函数,但我还不太确定如何完成所有这些以获取每个元素的名称/图像/类别。 谢谢
【问题讨论】:
您的代码对我有用。您确定您在此处粘贴的代码与您的项目中的代码相同吗? 是的,除了其他插座和按钮外,它的代码完全相同 你的json不正确"category": "Bird",结尾应该有',' 感谢 Noor Ahmed,这是一个错字,我忘记在这里更正了,因为我在这篇文章中更改了我的 json 的实际内容,以便更容易理解,但我的 json 文件格式正确;但是,由于下面的答案,我找到了错误的原因:我的结构的名称与我的 JSON 略有不同。谢谢大家! 无关,但let jsonData = try String(contentsOfFile: bundlePath).data(using: .utf8)
应该是let jsonData = try Data(contentsOfFile: bundlePath)
,不需要转换...
【参考方案1】:
我为你写了完整的答案..以此作为参考..祝你好运。
import UIKit
struct Animal : Codable
var name: String
var image: String
var category: String
struct Animals: Codable
var animal: [Animal]
class ViewController: UIViewController
override func viewDidLoad()
super.viewDidLoad()
let data = Data.readJsonFile(withName: "Animals")
do
let animalList = try JSONDecoder().decode(Animals.self, from: data!)
for item in animalList.animal
print(item.name)
catch
print("error")
extension Data
static func readJsonFile(withName name: String) -> Data?
do
if let bundlePath = Bundle.main.path(forResource: name, ofType: "json"),
let jsonData = try String(contentsOfFile: bundlePath).data(using: .utf8)
return jsonData
catch
print(error)
return nil
【讨论】:
谢谢!但它仍然在控制台中打印错误并且不打印任何 item.name 上面的代码对我来说很好用。确保你添加了 Animals.json 文件。 是的,问题出在我的结构中,一些参数的名称与 json 文件的名称不完全相同(有几个错别字),但现在它可以工作了,非常感谢!print("error")
:不,请不要那样做。而是:print("error: \(error)")
。打印错误,它对失败的原因进行了有意义的描述,并让您知道如何修复它!【参考方案2】:
您共享的代码实际上正在运行。
如果您遇到解码错误。可能原因会是
-
缺少任何空值或任何结构(动物)成员(名称、图像、类别)
所以你可以像可选的那样改变你的结构成员。因此,如果有任何失败情况,它可以保持零值。制作这样的结构
struct Animals: Codable
var animal: [Animal]?
struct Animal : Codable
var name: String?
var image: String?
var category: String?
访问值时不要忘记安全解包。
private func parse(jsonData: Data)
do
let decodedData = try JSONDecoder().decode(Animals.self, from: jsonData)
print("animal: ", decodedData.animal?.first?.name ?? "")
catch
print("decode error")
还有一个原因是类型转换错误。例如,成员(名称、图像、类别)在结构中被声明为字符串,但在 JSON 中,如果任何值是整数或不是字符串,则将是解码错误。你应该更正json
【讨论】:
就是这样!我的结构成员和我的 json 成员之间的不匹配,该死的错别字......print("decode error")
:不,请不要那样做。而是:print("decode error: \(error)")
。打印错误,它对失败的原因进行了有意义的描述,并让您知道如何修复它!以上是关于从嵌套的 JSON 中检索数据的主要内容,如果未能解决你的问题,请参考以下文章
如何在 laravel 6 中存储和检索嵌套的 JSON 数组
解析嵌套的 JSON 并将其保存到 SQLite 中,然后检索它
如何从在线 JSON API 中提取嵌套数据对象? [关闭]