Ios 使用Swift解析嵌套JSON数据的正确方法是什么?
我是Swift和iOS开发的新手,目前正在学习如何使用JSON数据 我正在尝试解析嵌套的JSON数据并显示以下输出:Ios 使用Swift解析嵌套JSON数据的正确方法是什么?,ios,json,swift,decode,Ios,Json,Swift,Decode,我是Swift和iOS开发的新手,目前正在学习如何使用JSON数据 我正在尝试解析嵌套的JSON数据并显示以下输出: White hex value is #ffffff Black hex value is #000000 Gray10 hex value is #f5f7f8 Gray20 hex value is #e8eced Gray30 hex value is #d5d9db Gray40 hex value is #b6bec2 Gray50 hex value is #8e99
White hex value is #ffffff
Black hex value is #000000
Gray10 hex value is #f5f7f8
Gray20 hex value is #e8eced
Gray30 hex value is #d5d9db
Gray40 hex value is #b6bec2
Gray50 hex value is #8e999e
Gray60 hex value is #69757a
Gray70 hex value is #495257
Gray80 hex value is #333a3d
Gray90 hex value is #1f2426
Purple10 hex value is #ffc7f2
Purple20 hex value is #f59de2
Purple30 hex value is #e07ecb
Purple40 hex value is #d160b7
Purple50 hex value is #b34fa0
Purple60 hex value is #964286
Purple70 hex value is #773569
Purple80 hex value is #5b284f
Purple90 hex value is #401c36
我能够解析一个简单的JSON文件,如下所示:
{
"color": {
"white": { "value": "#fff" },
"black": { "value": "#000" }
}
}
但是,我不知道如何正确地将嵌套数据(如下所示)解码为结构
,并将灰色
和紫色
键与其数值强度
键(10-90)连接起来,如上图所示
下面是我的游乐场代码,其中嵌套的JSON数据不起作用:
import Foundation
let json = """
{
"color": {
"white": { "value": "#fff" },
"black": { "value": "#000" },
"gray": {
"10": { "value": "#f5f7f8" },
"20": { "value": "#e8eced" },
"30": { "value": "#d5d9db" },
"40": { "value": "#b6bec2" },
"50": { "value": "#8e999e" },
"60": { "value": "#69757a" },
"70": { "value": "#495257" },
"80": { "value": "#333a3d" },
"90": { "value": "#1f2426" }
},
"purple": {
"10": { "value": "#ffc7f2" },
"20": { "value": "#f59de2" },
"30": { "value": "#e07ecb" },
"40": { "value": "#d160b7" },
"50": { "value": "#b34fa0" },
"60": { "value": "#964286" },
"70": { "value": "#773569" },
"80": { "value": "#5b284f" },
"90": { "value": "#401c36" }
}
}
}
""".data(using: .utf8)!
struct color: Codable {
let value: String
struct intensity {
let value: String
}
}
struct Entry: Codable {
let color: [String: color]
}
let jsonDecoder = JSONDecoder()
do {
let parsedJSON = try jsonDecoder.decode(Entry.self, from: json)
for color in parsedJSON.color {
print("\(color.key) hex value is \(color.value.value)")
}
}
最终,该功能将出现在iOS应用程序中
上面代码中显示的(部分)JSON数据是实际的生产数据。它是以这种形式提供给我的。因此,我无法更改JSON数据的定义或嵌套方式
我希望您能提供一些关于如何解析嵌套的JSON数据和如上所示显示数据的指导。除非您知道颜色名称,否则不能使用Codable。但是,您可以使用一些自定义解码逻辑来创建从上面的json定义的结构数组。示例操场代码可能如下所示
import UIKit
struct MyColor {
let name: String
let value: String
var console: String {
return name + " hex value is " + value
}
}
let json = "{\"color\":{\"white\":{\"value\":\"#fff\"},\"black\":{\"value\":\"#000\"},\"gray\":{\"10\":{\"value\":\"#f5f7f8\"},\"20\":{\"value\":\"#e8eced\"},\"30\":{\"value\":\"#d5d9db\"},\"40\":{\"value\":\"#b6bec2\"},\"50\":{\"value\":\"#8e999e\"},\"60\":{\"value\":\"#69757a\"},\"70\":{\"value\":\"#495257\"},\"80\":{\"value\":\"#333a3d\"},\"90\":{\"value\":\"#1f2426\"}},\"purple\":{\"10\":{\"value\":\"#ffc7f2\"},\"20\":{\"value\":\"#f59de2\"},\"30\":{\"value\":\"#e07ecb\"},\"40\":{\"value\":\"#d160b7\"},\"50\":{\"value\":\"#b34fa0\"},\"60\":{\"value\":\"#964286\"},\"70\":{\"value\":\"#773569\"},\"80\":{\"value\":\"#5b284f\"},\"90\":{\"value\":\"#401c36\"}}}}"
func parse() throws -> [MyColor] {
var myColors: [MyColor] = []
if let data = json.data(using: .utf8) {
if let root = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String:Any] {
if let colors = root["color"] as? [String:Any] {
for color in colors.keys {
if let valueNode = colors[color] as? [String:String] {
if let value = valueNode["value"] {
myColors.append(MyColor(name: color, value: value))
}
} else if let variants = colors[color] as? [String:[String:String]] {
for key in variants.keys {
if let variant = variants[key] {
if let value = variant["value"] {
myColors.append(MyColor(name: color + key, value: value))
}
}
}
}
}
}
}
}
return myColors
}
if let colors = try? parse() {
for color in colors {
print(color.console)
}
}
希望有帮助。我为此使用了JSONSerialization和两个结构,ColorData和ColorSaturation,并在初始化中处理了ColorData的大部分转换
struct ColorData {
let name: String
let values: [ColorSaturation]
init?(name: String, values: Any) {
self.name = name
if let single = values as? [String: String] {
guard let colorValue = single["value"] else { return nil }
self.values = [ColorSaturation(level: nil, value: colorValue)]
} else if let colorValues = values as? [String: [String: String]] {
var values = [ColorSaturation]()
for (key, colorValue) in colorValues {
guard let level = Int(key), let value = colorValue["value"] else { continue }
values.append(ColorSaturation(level: level, value: value))
}
self.values = values
} else {
return nil
}
}
}
struct ColorSaturation {
let level: Int?
let value: String
}
解码是这样做的
do {
if let result = try JSONSerialization.jsonObject(with: data) as? [String: [String: Any]] {
let colors = result["color"].map { $0.map {colorData in ColorData(name: colorData.key, values: colorData.value) }}
print(colors)
}
} catch {
print(error)
}
如果您事先不知道颜色名称是什么,最简单的方法就是忘记Codable并使用JSONSerialization。谢谢您提供的代码示例。他们很有帮助。