首页 > 解决方案 > 使用带有 JSONserialization 的 Structs 在 Swift 中解码嵌套的 JSON 数组和字典

问题描述

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

这是 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 接收的。

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

标签: iosswiftstructjson-serialization

解决方案


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

推荐阅读