首页 > 解决方案 > 你如何在 Swift 中解析递归 JSON?

问题描述

我从数据是递归的服务器接收 JSON。将其解析为方便的 Swift 数据结构的最佳方法是什么?

定义 Swift Codable 数据结构以将其解析为失败,因为不允许使用递归属性。

Swift 编译器报告:“值类型 'FamilyTree.Person' 不能具有递归包含它的存储属性”

{
   "familyTree": {
      "rootPerson": {
        "name": "Tom",
        "parents": {
           "mother": {
              "name": "Ma",
              "parents": {           
                 "mother": {
                    "name": "GraMa",
                    "parents": {}
                  },
                 "father": {
                    "name": "GraPa",
                    "parents": {}
                 }
               }
            },
           "father": {
              "name": "Pa",
              "parents": {}
            }
         }
      }
   }
}

理想情况下,最终结果是一堆从 rootPerson 对象开始指向它们的父对象和父对象的人对象。

标签: jsonswift

解决方案


第一个想法是创建结构,例如:

struct Person: Codable {
    var name: String
    var parents: Parents
}

struct Parents: Codable {
    var mother: Person?
    var father: Person?
}

但这不起作用,因为您不能拥有像这样的递归存储属性。

这是一种可能的工作解决方案:

let json = """
{
   "familyTree": {
      "rootPerson": {
        "name": "Tom",
        "parents": {
           "mother": {
              "name": "Ma",
              "parents": {
                 "mother": {
                    "name": "GraMa",
                    "parents": {}
                  },
                 "father": {
                    "name": "GraPa",
                    "parents": {}
                 }
               }
            },
           "father": {
              "name": "Pa",
              "parents": {}
            }
         }
      }
   }
}
"""

struct Person: Codable {
    var name: String
    var parents: [String: Person]
}

struct FamilyTree: Codable {
    var rootPerson: Person
}

struct Root: Codable {
    var familyTree: FamilyTree
}

let decoder = JSONDecoder()
let tree = try decoder.decode(Root.self, from: json.data(using: .utf8)!)
print(tree)

在操场上,这将正确解析 JSON。

parents字典Person将具有 和 等"mother""father"。这支持一个人有任意数量的父母和任何角色。


推荐阅读