使用具有 JSON 序列化的结构解码 Swift 中的嵌套 JSON 数组和字典

Decode nested JSON arrays and dictionaries in Swift using Structs with JSONserialization

我正在尝试创建一些结构来解码使用 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。我唯一能做的就是删除 "books" :其他所有内容都是从外部接收的 API.

感谢您就如何让它发挥作用提出任何建议。

您提供的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()