Swift:检查数据响应是数组还是dictonary

时间:2018-03-09 09:42:00

标签: json swift api parsing url

我正在调用API并将数据存储在数组中。 但如果没有数据调试器说: 预计会解码数组,但会找到字典。

失败的JSON响应是:

    '{"status":"Failed","msg":"Sorry It\'s Not Working"}'

成功的JSON响应是:

'[{"id":"509","name":"TEC TEST !"#!12","sortingId":"1"},
{"id":"510","name":"TEC TEST !"#!12","sortingId":"2"},
{"id":"511","name":"TEC TEST !"#!12","sortingId":"3"},
{"id":"512","name":"TEC TEST !"#!12","sortingId":"4"},
{"id":"513","name":"TEC TEST !"#!12","sortingId":"5"},
{"id":"514","name":"TEC TEST !"#!12","sortingId":"6"},
{"id":"519","name":"TEC TEST !"#!12","sortingId":"7"}]'

所以我想在以

取回我的回复之间切换
var result:[Items]?

var result:Items?

如果失败的JSON发送

我一直在谷歌上搜索Stackoverflow而没有运气

是否有解决方案可以说JSON是数组还是字典?

我的结构:

struct Items: Codable {
    let id: String?
    let sortingId: String?
    let name: String?
    let response: String?
    let status: String?
    let msg: String?
}

我对回复的处理:

var result:[Items]?
result = try JSONDecoder().decode([Items].self, from: data!)
DispatchQueue.main.async {
for item in result! {
  self.itemArray.append((name: item.name!, id: Int(item.id!)!, sortingId: Int(item.sortingId!)!))
  }
}

2 个答案:

答案 0 :(得分:1)

一种解决方案是编写一个自定义初始化程序,它有条件地解码数组或字典。

请让服务的所有者发送更一致的JSON。这很糟糕。至少该对象应始终具有键status的字典以及键items的数组或键msg

此代码首先尝试使用unkeyedContainer解码数组。如果失败则解码字典。

struct Item: Decodable {
    let id: String
    let sortingId: String
    let name: String
}

struct ItemData : Decodable {

    private enum CodingKeys: String, CodingKey { case status, msg }

    let status : String?
    let msg: String?
    var items = [Item]()

    init(from decoder: Decoder) throws {
        do {
            var unkeyedContainer = try decoder.unkeyedContainer()
            while !unkeyedContainer.isAtEnd {
                items.append(try unkeyedContainer.decode(Item.self))
            }
            status = nil; msg = nil
        } catch DecodingError.typeMismatch {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            status = try container.decodeIfPresent(String.self, forKey: .status)
            msg = try container.decodeIfPresent(String.self, forKey: .msg)
        }
    }
}

并称之为

result = try JSONDecoder().decode(ItemData.self, from: data!)

A - 可能更合适 - 替代方法是捕获JSONDecoder().decode行中的错误并使用两个简单的结构

struct Item: Decodable {
    let id: String
    let sortingId: String
    let name: String
}

struct ErrorData : Decodable {
    let status : String
    let msg: String
}

并将其命名为

do {

    let decoder = JSONDecoder()
    do {
       let result = try decoder.decode([Item].self, from: data!)
       print(result)
    } catch DecodingError.typeMismatch {
       let result = try decoder.decode(ErrorData.self, from: data!)
       print(result)
    }
} catch { print(error) }  

一个很大的好处是所有属性都是非可选的。

答案 1 :(得分:0)

首先,JSON不包含任何数组。它非常容易阅读JSON。只有2(两个!)集合类型,array []和字典{}。如您所见,JSON字符串中根本没有方括号。    it will helpful