使用 SwiftyJSON 将 JSON 解析为结构
Posted
技术标签:
【中文标题】使用 SwiftyJSON 将 JSON 解析为结构【英文标题】:Parsing JSON to a struct with SwiftyJSON 【发布时间】:2020-05-20 18:17:52 【问题描述】:我有一个简单的结构来处理来自 SwiftyJSON 的数据解析
struct Threads
var threads:[ThreadDetail]
struct ThreadDetail
var title:String
var username:String
var prefix_id:Int
这是 API 响应的示例
"threads": [
"first_post_id": 258535,
"prefix_id": 1,
"thread_id": 50204,
"title": "Testing board title",
"user_id": 20959,
"username": "test",
"view_count": 247,
现在这是我无法弄清楚的部分
Alamofire.request(url, method: .get, headers: headers).validate().responseJSON response in
switch response.result
case .success(let value):
let json = JSON(value)
for item in json["threads"].arrayValue
//how should it be written here?
case .failure(let error):
print(error)
【问题讨论】:
为什么不用codable? 你的问题是什么? 在得到 JSON 之后,我只是不知道如何将它们实际解析到预制结构中。 查看Codable。在您的情况下,只需将Threads
和ThreadDetail
与Codable
一致,就应该相当简单。
【参考方案1】:
声明您的模型并使其符合 Codable。
struct Response: Codable
let threads: [Thread]
// MARK: - Thread
struct Thread: Codable
let firstPostID, prefixID, threadID: Int
let title: String
let userID: Int
let username: String
let viewCount: Int
enum CodingKeys: String, CodingKey
case firstPostID = "first_post_id"
case prefixID = "prefix_id"
case threadID = "thread_id"
case title
case userID = "user_id"
case username
case viewCount = "view_count"
之后,使用 JSONDecoder 将数据转换为模型
Alamofire.request(urlString).response
response in
guard let data = response.data else return
do
let decoder = JSONDecoder()
let threadsWrapper = try decoder.decode(Response.self, from: data)
catch let error
print(error)
使用此网站将您的 JSON 转换为 Codable https://app.quicktype.io/
【讨论】:
如果你使用 Alamofire 5,你会得到一个responseDecodable
方法,它会为你解析你的 Decodable
类型。【参考方案2】:
据我所知,你可以按照 SwiftyJSON 来做到这一点:
Alamofire.request(url, method: .get, headers: headers).validate().responseJSON response in
switch response.result
case .success(let value):
let json = JSON(value)
var models = [ThreadDetail]()
for item in json["threads"].arrayValue
let model = ThreadDetail(title: item["title"].stringValue,
username: item["username"].stringValue,
prefix_id: item["prefix_id"].intValue)
models.append(model)
// do whatever you need with models
case .failure(let error):
print(error)
但实际上,正如Frankenstein 所说,解决问题的最佳方法就是让您的模型符合 Codable。
【讨论】:
【参考方案3】:我个人使用我为使用 JSON 的应用程序定制的一个名为 Weave 的库。它建立在 NSURLSession
和完全原生的 Swift 之上。当您使用WVRequest.request()
创建请求时,对于参数outputType
,请使用类型.json
。
这是您使用 Weave 的上述代码:
WVRequest.start(url, requestType: .get, outputType:.json, headers: headers).start() response in
if response.success
// Cast to a dictionary
let json = (response as! WVJSONResponse).json as! [String:Any]
let threads = json["threads"] as! [Thread]
// From here, just use a for loop, and create an instance of your Thread class for each iteration.
else
print("Error!")
希望有帮助!
【讨论】:
【参考方案4】:struct Temperature: Codable
let high: Double
let low: Double
struct Bluh: Codable, Identifiable
var temperature: JSON
func getTemperatures() -> Temperature?
do
let decoder = JSONDecoder()
return try decoder.decode(Temperature.self, from: temperature.rawData())
catch let error
print(error)
你也可以这样做。如果您的数据是 SWIFY JSON 并尝试转换为结构。
【讨论】:
以上是关于使用 SwiftyJSON 将 JSON 解析为结构的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 SwiftyJSON 在 Swift 中解析这个 JSON 对象?