json 如何修复?预期解码字典〈String,Any>,但却找到了字符串/数据

2wnc66cl  于 2022-11-26  发布在  其他
关注(0)|答案(3)|浏览(122)

这里出了什么问题?或者我应该如何解码,我不会使用jsonserialize。

let jsonData = try! Data(contentsOf: urls[0])
let decoder = JSONDecoder()
let d = try decoder.decode([String: JSON].self, from: jsonData)

文件内容是一个简单JSON:

{"name": "fff", "price": 10}

还有我的JSON代码:

public enum JSON: Decodable {
    case string(String)
    case number(Float)
    case object([String:JSON])
    case array([JSON])
    case bool(Bool)
}
kadbb459

kadbb4591#

您需要添加一个自定义的init(from:),尝试在其中解码为每个可能的枚举情况,直到成功或引发错误为止
这里是一个简短的版本,处理三种情况

struct EnumDecoderError: Error {}

public init(from decoder: Decoder) throws {
    let container = try decoder.singleValueContainer()
    if let string = try? container.decode(String.self) {
        self = JSON.string(string)
    } else if let number = try? container.decode(Float.self) {
        self = JSON.number(number)
    } else if let array = try? container.decode([JSON].self) {
        self = JSON.array(array)
    } else {
        throw EnumDecoderError()
    }
}

正如@LeoDabus在注解中提到的,我们可以捕获typeMismatch错误(并直接抛出任何其他错误),或者像以前一样,如果没有解码成功,则在结尾抛出一个错误。(同样是一个缩短的版本)

public init(from decoder: Decoder) throws {
    let container = try decoder.singleValueContainer()

    do {
        let string = try container.decode(String.self)
        self = JSON.string(string)
    } catch DecodingError.typeMismatch {
        do {
            let number = try container.decode(Float.self)
            self = JSON.number(number)
        } catch DecodingError.typeMismatch {
            do {
                let array = try container.decode([JSON].self)
                self = JSON.array(array)
            } catch DecodingError.typeMismatch {
                throw DecodingError.typeMismatch(JSON.self, .init(codingPath: decoder.codingPath, debugDescription: "Data type is not supported"))
            }
        }
    }
}
wztqucjr

wztqucjr2#

首先,不需要在JSON枚举中维护数据类型来解析响应。
如果您将对象与从本地维护的API或JSON文件接收的响应结构进行匹配,JSONDecoder将能够使用适当的数据类型进行解析
以您的json文件为例:
{【品名】:【fff】,【价格】:10个月}
解析此结构的建议方法如下

  • 根据需要创建一个结构体或类。
struct Product: Decodable {
  var name: String?
  var price: Int?

}
我标记了两个vars选项,以防在JSON响应中不存在该字段时处理失败。

  • 分析结构

通过创建解码器示例并设置Product.Self,使用在上一步中创建的product结构来解析对象

let decoder = JSONDecoder()
let productObject = try decoder.decode(Product.self, from: jsonData)

如果您在JSON响应中有相同结构的对象数组,请使用以下代码:

let productObjects = try decoder.decode([Product].self, from: jsonData)

只需在产品对象前后包含[]

6ie5vjzr

6ie5vjzr3#

你需要把它解码成一个结构

private struct MyData: Codable {
    var name: String?
    var price: Int?
}

...
let jsonData = try! Data(contentsOf: urls[0])
let d = try JSONDecoder().decode(MyData.self, from: jsonData)
...

相关问题