【问题标题】:How to parse nested json? Swift如何解析嵌套的json?迅速
【发布时间】:2019-01-09 12:08:17
【问题描述】:

我有一个本地 json 字符串,我正在尝试解析它,但是当我尝试这样做时,我不断收到错误消息。我也在嵌套字典中看到了这个错误,但找不到错误。 下面是json字符串

let jsonNestedString  = "{\"meta\":{\"page\":1,\"total_pages\":4,\"per_page\":10,\"total_records\" : 38}, \"reweries\":[\"id\":1234,\"name\":\"saintArnold\"},{\"id\":52892,\"name\":\"buffalo bayou\"]}"

我正在通过 Codable 执行此过程,下面是我为此创建的结构

struct PagedBreweries:Codable{
    struct Meta:Codable{
        let page : Int
        let total_pages:Int
        let per_page:Int
        let total_records: Int
        enum CodingKeys: String, CodingKey{
            case page
            case total_pages
            case per_page
            case total_records
        }
    }

    struct Brewery :Codable{
        let id:Int
        let name:String

    }
    let meta:Meta
    let breweries :[Brewery]
}

然后将此数据解析为如下函数

    func jsonNested(){
    let jsonData = jsonNestedString.data(using: .utf8)
    let decoder = JSONDecoder()
    let data  = try! decoder.decode(PagedBreweries.Meta.self, from: jsonData!)
    print(data)
}

当我尝试构建时,我得到的错误出现在 try!解码器.decode
命令 错误是

线程 1:致命错误:“尝试!”表达式意外引发错误:Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "page", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \" page\", intValue: nil) (\"page\").", underlyingError: nil))

谁能提供解决方案? 提前致谢

【问题讨论】:

  • 这可能不是原因,但]age 部分看起来有点可疑。
  • 您的 JSON 无效。在尝试使用它之前,您应该始终在像 this 这样的验证器上测试您的 JSON。
  • 我尝试了一个 json 验证器,它确认这个 json 实际上是有效的
  • 这部分也无效:\"reweries\":[\"id\":1234,\"name\":\"saintArnold\"}.
  • 阅读错误消息,它非常具有描述性:字符 64 是 = 38 周围的区域。JSON 中的键/值对始终由 冒号 (:)。大约 20 个字符后,:[ 之后缺少一个左大括号

标签: ios json swift api codable


【解决方案1】:

正确的json

{
    "meta": {
        "page": 1,
        "total_pages": 4,
        "per_page": 10,
        "total_records": 38
    },
    "reweries": [{
    "id": 1234,
    "name": "saintArnold"
    },
    {
    "id": 52892,
    "name": "buffalo bayou"
    }
    ]
}

struct Root: Codable {
    let meta: Meta
    let reweries: [Rewery]
}

struct Meta: Codable {
    let page, totalPages, perPage, totalRecords: Int

    enum CodingKeys: String, CodingKey {  // snake case may be used 
        case age = "page"
        case totalPages = "total_pages"
        case perPage = "per_page"
        case totalRecords = "total_records"
    }
}

struct Rewery: Codable {
    let id: Int
    let name: String
}

  let jsonNestedString  = """
    {\"meta\":{\"page\":1,\"total_pages\":4,\"per_page\":10,\"total_records\":38}, \"reweries\":[{\"id\":1234,\"name\":\"saintArnold\"},{\"id\":52892,\"name\":\"buffalo bayou\"}]}
"""

  // or 

let jsonNestedString  = """

{
    "meta": {
        "page": 1,
        "total_pages": 4,
        "per_page": 10,
        "total_records": 38
    },
    "reweries": [{
    "id": 1234,
    "name": "saintArnold"
    },
    {
    "id": 52892,
    "name": "buffalo bayou"
    }
    ]
}


"""

do {

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


} catch  {
    print(error)
}

【讨论】:

  • 我的 json 是有效的,我已经在多个站点上测试过,但仍然出现相同的错误
  • 另外,您已经更改了代码,您建议的上述结构不是嵌套的
  • @vgvishesh23113 我不知道你为什么需要斜杠,但我添加了它们,请参阅编辑......
  • 我需要斜杠以使其成为 swift 中的有效字符串
  • 不,你不必有一个带有 """str""" 的多行字符串,请参阅编辑............
【解决方案2】:

JSON 已损坏,您正在解码错误的根对象。

这是正确 JSON 被你的结构解码并符合 Swift 命名约定

let jsonNestedString  = """
{"meta":{"page":1,"total_pages":4,"per_page":10,"total_records" : 38}, "breweries":[{"id":1234,"name":"saintArnold"},{"id":52892,"name":"buffalo bayou"}]}
"""

struct PagedBreweries : Codable {
    struct Meta : Codable {
        let page : Int
        let totalPages:Int
        let perPage:Int
        let totalRecords: Int
    }

    struct Brewery : Codable {
        let id:Int
        let name:String

    }
    let meta:Meta
    let breweries :[Brewery]
}

func jsonNested(){
    let jsonData = Data(jsonNestedString.utf8)
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let data  = try! decoder.decode(PagedBreweries.self, from: jsonData)
    print(data)
}

jsonNested()

// Printed result: 
// PagedBreweries(meta: __lldb_expr_1.PagedBreweries.Meta(page: 1, totalPages: 4, perPage: 10, totalRecords: 38), breweries: [__lldb_expr_1.PagedBreweries.Brewery(id: 1234, name: "saintArnold"), __lldb_expr_1.PagedBreweries.Brewery(id: 52892, name: "buffalo bayou")])

【讨论】:

  • 终于成功了,非常感谢你的时间朋友
猜你喜欢
  • 1970-01-01
  • 2020-06-02
  • 2023-03-20
  • 2021-02-25
  • 1970-01-01
  • 1970-01-01
  • 2020-02-22
  • 2019-03-22
  • 1970-01-01
相关资源
最近更新 更多