快速解码复合结构数据 [英] Swift decode composite struct data

查看:132
本文介绍了快速解码复合结构数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下json数据并尝试对其进行解析,但是我得到了许多对象,但是数组中的对象本身均为nil.

I have the following json data and trying to parse it, but I get number of objects, but object itself in the array all are nil.

我不想在以下json对象中解码origin.

I do not want to decode the origin in the following json object.

顺便说一下,以下字符串首先转换为数据,然后将其传递给下面的parse函数.

By the way, the following string is first converted to data and then passed it to parse function below.

数据如下:

[ 
 [
   {"id": "152478", "age": 20},
   {"character": "king","isDead":"no", "canMove" :"yes", "origin" :"south africa"}
 ],
 [
  {"id": "887541", "age": 22},
  {"character": "lion", "isDead":"no", "canMove" :"yes", "origin" :"south america"}
 ]
]

模型

struct A: Codable {
    let id: String?
    let age: Int?

    enum CodingKeys: String, CodingKey {
        case id
        case age
    }
}

struct B: Codable {
    let character, isDead, canMove: String?

    enum CodingKeys: String, CodingKey {
        case character
        case isDead
        case canMove
    }
}

struct AB :Codable {
  let a: A
  let b: B

  init(from decoder: Decoder) throws {
    guard var container = try? decoder.unkeyedContainer() else { 
         //no error here!!!       
         fatalError()   
     }
    print(container)
    guard let a = try? container.decode(A.self),
        let b = try? container.decode(B.self)
      else {
        // throw since we didn't find A first, followed by B
        throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: nil)
        )
      }
    self.a = a
    self.b = b
  }
}

ViewModel

private func parse(jsonData : Data){
    do {
        let decoder = JSONDecoder()
        let response = try decoder.decode([AB].self, from: jsonData)
        print(response)
    }
    catch (let error as NSError) {
        print(error)
    }
}

更新: 顺便说一句,以下代码有效.我想知道为什么上面的代码无法处理?

UPDATE: By the way, the following code works. I wonder why above code does not handle?

private func parseData(jsonData : Data)
{
    do {
        response = try JSONSerialization.jsonObject(with: jsonData) as! [[[String: Any]]]
        for i in 0..<response.count
        {
            for j in 0..<response[i].count
            {
                if j == 0
                {
                    let jsonDat = (try? JSONSerialization.data(withJSONObject:response[i][j]))!
                    let b = try JSONDecoder().decode(A.self, from: jsonDat)
                }
                else if j == 1
                {
                    let jsonDatt = (try? JSONSerialization.data(withJSONObject:response[i][j]))!
                    let a = try JSONDecoder().decode(B.self, from: jsonDatt)
                }
            }
        }
        print(response)
    }
    catch let error as NSError {
        print(error)
    }
}

更新II:

如果我进行以下更改[AB]-> [[AB]],然后按如下方式对其进行调用,它将对数据进行解码,但最终在数组中,A对象具有值,但B nil或反之反之亦然.

If I make the following changes [AB] --> [[AB]], and then I call it as follows, it decodes data, but in the array I end up, A object has values, but B nil, or vice versa.

let response = try decoder.decode([[AB]].self, from: jsonData)


guard var container = try? decoder.singleValueContainer() else
{
    fatalError()
}

推荐答案

我刚刚在操场上尝试了这段精简的代码

I just tried this stripped-down version of your code in a playground

let json = """
[
 [
   {"id": "152478", "age": 20},
   {"character": "king","isDead":"no", "canMove" :"yes", "origin" :"south africa"}
 ],
 [
  {"id": "887541", "age": 22},
  {"character": "lion", "isDead":"no", "canMove" :"yes", "origin" :"south america"}
 ]
]
""".data(using: .utf8)!

struct A: Codable {
    let id: String
    let age: Int
}

struct B: Codable {
    let character, isDead, canMove: String
}

struct AB: Codable {
    let a: A
    let b: B

    init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()

        self.a = try container.decode(A.self)
        self.b = try container.decode(B.self)
    }
}

do {
    let ab = try JSONDecoder().decode([AB].self, from: json)
    print(ab.count)
    print(ab[0].a.id)
    print(ab[0].b.character)

    print(ab[1].a.id)
    print(ab[1].b.character)
} catch {
    print(error)
}

,效果很好.也许这有助于弄清发生了什么.

and it works just fine. Maybe this helps figuring out what's going on.

这篇关于快速解码复合结构数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆