使用可解码和对象键入不匹配

时间:2018-04-19 21:22:34

标签: swift realm alamofire decodable

我从服务器解析数据时遇到问题。我有JSON,它有一个对象数组,如下所示:

{
    "items": [
        {
            "itemType": {
                "id": 12,
                "tagId": "FCHA78558D"
            },
            "parts": [
                {
                    "partId": 52,
                    "manufacturer": "xxx"
                },
                {
                    "partId": 53,
                    "manufacturer": "xxx"
                },
                {
                    "partId": 54,
                    "manufacturer": "xxx"
                }
            ],
            "description": "yyy"
        },
        {
            "itemType": {
                "id": 13,
                "tagId": "FCHA755158D"
            },
            "parts": [
                {
                    "partId": 64,
                    "manufacturer": "xxx"
                },
                {
                    "partId": 65,
                    "manufacturer": "xxx"
                }
            ],
            "description": "zzz"
        }
    ]
}

我只想获得这一个对象数组,所以我实现了这个类:

class User : Object, Decodable {
   var items = List<Equipment>()
}

在Alamofire中我正在下载JSON,将其解析为数据然后在do-catch块中我收到错误:

let items = try JSONDecoder().decode(User.self, from: receivedValue)

错误:

▿ DecodingError
  ▿ typeMismatch : 2 elements
    - .0 : Swift.Array<Any>
    ▿ .1 : Context
      ▿ codingPath : 2 elements
        - 0 : CodingKeys(stringValue: "items", intValue: nil)
        ▿ 1 : _JSONKey(stringValue: "Index 0", intValue: 0)
          - stringValue : "Index 0"
          ▿ intValue : Optional<Int>
            - some : 0
      - debugDescription : "Expected to decode Array<Any> but found a dictionary instead."
      - underlyingError : nil

这很奇怪,因为它确实是一个对象数组。我尝试将我的items属性设置为String以查看结果,然后我得到: - debugDescription : "Expected to decode String but found an array instead." 我有几次这个错误,但我总是设法找到解决方案。

1 个答案:

答案 0 :(得分:1)

我认为您对previous question的答案使用List条件符合Decodable。我不完全理解为什么它在这个特定情况下不起作用,但我会调查。

在此之前,您可以通过手动实现init(from decoder:Decoder)功能来进行解码。

class User : Object, Decodable {
    let items = List<Equipment>()

    private enum CodingKeys: String, CodingKey {
        case items
    }
    required convenience init(from decoder:Decoder) throws {
        self.init()
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let itemsArray = try container.decode([Equipment].self, forKey: .items)
        self.items.append(objectsIn: itemsArray)
    }
}