gpt4 book ai didi

swift - 在 swift 4 中解码动态 JSON 结构

转载 作者:行者123 更新时间:2023-11-28 09:48:37 24 4
gpt4 key购买 nike

我有以下问题,我不确定如何处理。

我的 JSON 响应可能如下所示:

{ 
"data": {
"id": 7,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NDY1MTU0NDMsImRhdGEiOiJ2bGFkVGVzdCIsImlhdCI6MTU0NjUwODI0M30.uwuPhlnchgBG4E8IvHvK4bB1Yj-TNDgmi7wUAiKmoVo"
},
"error": null
}

或者像这样:

{
"data": [{
"id": 12
}, {
"id": 2
}, {
"id": 5
}, {
"id": 7
}],
"error": null
}

所以简而言之,数据可以是单个对象或数组。我所拥有的是:

struct ApiData: Decodable {
var data: DataObject?
var error: String?
}

struct DataObject: Decodable {
var userId: Int?

enum CodingKeys: String, CodingKey {
case userId = "id"
}
}

这对于第一个用例工作正常,但一旦数据变成

var 数据:[DataObject?]

如何在不重复代码的情况下实现动态化?

编辑:这也是我解码对象的方式

 func makeDataTaskWith(with urlRequest: URLRequest, completion: @escaping(_ apiData: ApiData?) -> ()) {
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)

session.dataTask(with: urlRequest) {
(data, response, error) in
guard let _ = response, let data = data else {return}

if let responseCode = response as? HTTPURLResponse {
print("Response has status code: \(responseCode.statusCode)")
}

do {
let retreived = try NetworkManager.shared.decoder.decode(ApiData.self, from: data)
completion(retreived)
} catch let decodeError as NSError {
print("Decoder error: \(decodeError.localizedDescription)\n")
return
}
}.resume()
}

最佳答案

如果 data 可以是单个对象或数组,则编写一个自定义初始化器,它首先解码一个数组,如果发生类型不匹配错误,则解码单个对象。 data 无论如何都声明为数组。

由于 token 仅出现在单个对象中,因此该属性被声明为可选。

struct ApiData: Decodable {
let data : [DataObject]
let error : String?

private enum CodingKeys : String, CodingKey { case data, error }

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
do {
data = try container.decode([DataObject].self, forKey: .data)
} catch DecodingError.typeMismatch {
data = [try container.decode(DataObject.self, forKey: .data)]
}
error = try container.decodeIfPresent(String.self, forKey: .error)
}
}


struct DataObject: Decodable {
let userId : Int
let token : String?

private enum CodingKeys: String, CodingKey { case userId = "id", token }
}

编辑:可以改进您接收数据的代码。您应该添加更好的错误处理以返回所有可能的错误:

func makeDataTaskWith(with urlRequest: URLRequest, completion: @escaping(ApiData?, Error?) -> Void) {
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)

session.dataTask(with: urlRequest) {
(data, response, error) in
if let error = error { completion(nil, error); return }

if let responseCode = response as? HTTPURLResponse {
print("Response has status code: \(responseCode.statusCode)")
}

do {
let retreived = try NetworkManager.shared.decoder.decode(ApiData.self, from: data!)
completion(retreived, nil)
} catch {
print("Decoder error: ", error)
completion(nil, error)
}
}.resume()
}

关于swift - 在 swift 4 中解码动态 JSON 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54019877/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com