繁体   English   中英

检查 json 响应是数组还是整数或字符串作为键?

[英]check the json response is array or int or string for a key?

我有 json 响应,其中“产品”键有时具有 int 值,在某些情况下它有一个数组? 如何检查它是否具有数组或 Int?

"products": 25

或者

"products": [77,80,81,86]

我正在使用这个

self.productsCount = mResp["products"] as! [Int]

但是每次没有数组时它都会崩溃。

现在我不知道如何检查这个,因为我有不同的 Int 和 Array 选项?

请帮助我。谢谢

它崩溃是因为你强制解包为一个整数数组,即使你只有一个整数。 解决方案是检查两者:

self.productsCount = mResp["products"] as? [Int] ?? mResp["products"] as? Int

其他解决方案

if let proCount = mResp["products"] as? [Int] { 
  self.productsCount = proCount
} else {
  self.productsCount = mResp["products"] as? Int
}

这里没有必要回退到Any 甚至像这样有问题的 JSON 也可以使用Codable处理。 您只需要继续尝试不同的类型,直到其中一种有效。

struct Thing: Decodable {
    let products: [Int]

    enum CodingKeys: String, CodingKey {
        case products
    }

    init(from decoder: Decoder) throws {
        // First pull out the "products" key
        let container = try decoder.container(keyedBy: CodingKeys.self)

        do {
            // Then try to decode the value as an array
            products = try container.decode([Int].self, forKey: .products)
        } catch {
            // If that didn't work, try to decode it as a single value
            products = [try container.decode(Int.self, forKey: .products)]
        }
    }
}


let singleJSON = Data("""
{ "products": 25 }
""".utf8)

let listJSON = Data("""
{ "products": [77,80,81,86] }
""".utf8)

let decoder = JSONDecoder()

try! decoder.decode(Thing.self, from: singleJSON).products   // [25]
try! decoder.decode(Thing.self, from: listJSON).products     // [77, 80, 81, 86]

这是您想要的临时解决方案。 使用“任何”类型检查可能的类型。

    var anyType : Any!
    anyType = "123"
    anyType = ["Test","Test1"]
    anyType = 1
    if anyType is Array {
        print("is Array")
    }else if anyType is String {
        print("is String")
    }else if anyType is Int {
        print("is Int")
    }

假设您的 json 名称是jsonData

检查IntArray Int

if let intVal = jsonData["products"] as? Int {
    print("Products is a Integer: ", intVal)

} else if let jsonArr = jsonData["products"] as? [Int] {

    var intVals = [Int]()
    for json in jsonArr {
        intVals.append(json)
    }
    print("Json is array of Int: ", intVals)
}
let dict = [77,80,81,86]//Pass your parameter or parsed json value
 if dict is Array<Any> {
    print("Yes, it's an Array")
}
else{
      print("NO, it's not an Array")

}

通用解决方案是这样的,

let products = mResp["products"] as? Any
if let item = products as? [Int] {
    print("array", item)
} else if let item = products as? Int {
    print("Integer", item)
}

使用Generics以获得更好的解决方案并在解码此模型时提供类型。

struct Product<T: Codable>: Codable {
    let products: T?
}

您可以将它与嵌套的try catch一起使用:

do {
    let product = try JSONDecoder().decode(Product<Int>.self, from: data)
    print(product)
} catch {
    do {
        let product = try JSONDecoder().decode(Product<[Int]>.self, from: data)
        print(product)
    } catch {
        print(error)
    }
}

注意:此解决方案假定可编码结构中不超过几个不同的类型变化属性。 如果有多个类型不同的属性,我建议使用接受的答案中提供的自定义init(decoder:) ,这将是更好的设计,而不是使用try-catch树。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM