如何在Swift中解析递归JSON?

如何在Swift中解析递归JSON?,json,swift,Json,Swift,我从一个数据是递归的服务器接收JSON。将其解析为方便的Swift数据结构的最佳方法是什么 定义Swift可编码数据结构以将其解析为失败,因为不允许递归属性 Swift编译器报告:值类型“FamilyTree.Person”不能具有递归包含它的存储属性 { "familyTree": { "rootPerson": { "name": "Tom", "parents": { "mother": {

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

定义Swift可编码数据结构以将其解析为失败,因为不允许递归属性

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

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

理想情况下,最终结果将是一组person对象,从rootPerson对象开始指向其父对象和母对象。

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

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


人的父母字典将有诸如母亲和父亲之类的键。这支持一个人有任意数量的父母担任任何角色。

使用类的可能实现。 Swift 5合成类的默认初始值设定项。不记得斯威夫特4的情况

import Foundation

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




final class Parents: Codable{
    let mother: Person?
    let father: Person?

}

final class  Person: Codable{
    let name: String
    let parents: Parents?
}


final class RootPerson: Codable {
    var rootPerson: Person
}

final class Root: Codable {
    var familyTree: RootPerson
}

var jsonData = json.data(using: .utf8)!


do{
   let familyTree = try JSONDecoder().decode(Root.self, from: jsonData)
    print("Ma •••>", familyTree.familyTree.rootPerson.parents?.mother?.name)
    print("GraPa •••>", familyTree.familyTree.rootPerson.parents?.mother?.parents?.father?.name)
    print("Shoud be empty •••>", familyTree.familyTree.rootPerson.parents?.mother?.parents?.father?.parents?.father?.name)
} catch {
    print(error)
}