所以我有一个JSON文件,我需要解析和更新标签和图像。在我的情节提要中,我有4个标签(动物的图像,区域,重量和长度)和uiimage,我需要在其中贴上图片。 我需要通过解析JSON更新标签和图像。 这是我能够到达的距离...
我的JSON看起来像这样:
"data":[
{
"name":"Lion",
"thumbnail":"https://kopelion.org/wp-content/uploads/2016/10/Kimani.jpg",
"region":"Africa",
"stats":{
"max_weight":180,
"length":250
}
}
]
我试图通过写作来解决这个问题:
override func viewDidLoad() {
super.viewDidLoad()
guard let path = Bundle.main.path(forResource: "data", ofType: "json") else { return }
let url = URL(fileURLWithPath: path)
do {
let data = try Data(contentsOf: url)
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
print(json)
guard let array = json as? [Any] else { return }
for animal in array {
guard let animalDict = animal as? [String: Any] else { return }
guard let animalName = animalDict["name"] as? String else { return }
guard let animalRegion = animalDict["region"] as? String else { return }
guard let animalStats = animalDict["stats"] as? String else { return }
print(animalName)
print(animalRegion)
print(animalStats)
}
} catch {
print(error)
}
}
答案 0 :(得分:0)
您需要在类中具有要设置的情节提要项的属性。例如:
@IBOutlet weak var name: UILabel! // outside functions but inside class, and hooked up in Storyboard
// inside viewDidLoad
name.text = animalDict["name"] as? String
除非您真的需要它们,否则我不会打扰中间变量。
答案 1 :(得分:0)
首先要注意的是,多数情况下,罪魁祸首是json
文件本身,就像您的情况一样。
您首先需要fix
文件代码中的json
和adding "{" at the top
"}" at the bottom
json
代码。
这将使其valid json
然后是do the following
替换您的代码行:
// 1
guard let array = json as? [Any] else { return }
// 2
guard let animalStats = animalDict["stats"] as? String else { return }
与此:
// 1
guard let dictionary = json as? [String:[Any]] else { return }
guard let array = dictionary["data"] else { return }
//2
guard let animalRegion = animalDict["region"] as? String else { return }
问题提示:1.使用https://codebeautify.org/jsonviewer
等在线工具检查json
- 尝试使用JSONDecoder和JSONEncoder而不是JSONSerialization
答案 2 :(得分:0)
由于您负责JSON,因此删除封闭的字典data
,这是不需要的。
[{
"name":"Lion",
"thumbnail":"https://kopelion.org/wp-content/uploads/2016/10/Kimani.jpg",
"region":"Africa",
"stats":{
"max_weight":180,
"length":250
}
}]
创建两个结构
struct Animal: Decodable {
let name: String
let thumbnail: URL
let region: String
let stats: Stats
}
struct Stats: Decodable {
let maxWeight, length: Int
}
在视图控制器中声明一个数据源数组
var animals = [Animal]()
在viewDidLoad
中,用JSONDecoder
解析数据,并将结果分配给数据源数组
override func viewDidLoad() {
super.viewDidLoad()
let url = Bundle.main.url(forResource: "data", withExtension: "json")!
let data = try! Data(contentsOf: url)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
self.animals = try! decoder.decode([Animal].self, from: data)
}
实际上不需要所有guard
和try
。该文件必须在编译时存在,并且不能在运行时进行修改,因此代码不得崩溃。
您可以通过
获得动物的属性let animal = animals[0]
let name = animal.name
let weight = animal.stats.weight
print(name, weight)
假设JSON中有更多动物使用循环
for animal in animals {
let name = animal.name
let weight = animal.stats.weight
print(name, weight)
}
不清楚如何更新标签,因为问题中没有有关该设计的重要信息。
要使用URLSession
异步加载图像