【问题标题】:Decode nested JSON arrays and dictionaries in Swift using Structs with JSONserialization使用带有 JSONserialization 的 Structs 在 Swift 中解码嵌套的 JSON 数组和字典
【发布时间】:2020-06-10 16:33:40
【问题描述】:

我正在尝试创建一些结构来解码使用JSONSerialization.jsonObject(with: data, options: [])从 API 接收的一些 JSON

这就是 JSON 的样子:

{"books":[{"title":"The Fountainhead.","author":"Ayn Ranyd"},{"title":"Tom Sawyer","author":"Mark Twain"},{"title":"Warhol","author":"Blake Gopnik"}]}

这是我试图用于解码的结构。

struct BooksReturned : Codable {
        let books : [Book]?
    }
    struct Book : Codable {
        let BookParts: Array<Any>?
    }
    struct BookParts : Codable {
        let titleDict : Dictionary<String>?
        let authorDict : Dictionary<String>?
    }

错误是:

The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.})))

我用来解码的非工作代码是:

let task = session.dataTask(with: url) { data, response, error in
            if let data = data, error == nil {
                let nsdata = NSData(data: data)
                DispatchQueue.main.async {
                    if let str = String(data: data, encoding: .utf8) {

                        let json = try? JSONSerialization.jsonObject(with: data, options: [])                        
                        do {

                            let mybooks = try JSONDecoder().decode(BooksReturned.self, from: data)
                             //do something with book
                            }

                        } catch {
                            print(error.localizedDescription)
                            print(error)
                        }
                    }
                }
            } else {
                // Failure
            }
        }
        task.resume()
    }

我更改 JSON 的能力非常有限。我唯一能做的就是删除“书籍”:其他所有内容都是从外部 API 接收的。

感谢您提供有关如何使其工作的任何建议。

【问题讨论】:

  • 错误是说你有无效的 JSON。你能打印let res = data.map { String(format: "02hhX", $0) }.joined()吗?
  • 在您学习绳索时很好。但是当你有很多 json 来解析和创建模型时,我更喜欢像 app.quicktype.io 这样的工具,它是一种创建模型的快速方法,可以为你完成所有检查,并用几种不同的语言创建模型。试一试。
  • 哇,刚刚试过 app.quicktype.io。太棒了。

标签: ios swift struct json-serialization


【解决方案1】:

您提供的JSON 似乎是有效的。修改你的Book模型和解码部分如下。

型号:

struct Book: Codable {
    let title, author: String
}

解码:

let task = session.dataTask(with: url) { data, response, error in
    if let data = data, error == nil {
        DispatchQueue.main.async {
            do {
                let mybooks = try JSONDecoder().decode(BooksReturned.self, from: data)
                print(mybooks)
            }
        } catch {
            print(error.localizedDescription)
            print(error)
        }
    }
} else {
    // Failure
}
task.resume()

【讨论】:

  • 我是否保留 BooksReturned 结构并摆脱 BookParts 以便获得 BooksReturned 和 Book 的新代码?
  • 去掉BookParts 并保留上面给出的BookReturned,我们正在尝试解码BookReturned
  • 跟进问题。我的印象是 [Books] 会给我一系列书籍,但是当我尝试调用 BooksReturned[0] 时,我收到 Type BooksRetuned 没有下标成员的错误。我将如何获得第一件物品?
  • 我终于可以用 let abook = mybooks?.books?[0] 来引用它。我猜实际的数组是书籍,而不是 BooksReturned
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-25
  • 2022-01-24
  • 2021-05-03
相关资源
最近更新 更多