【问题标题】:Parsing JSON to a struct with SwiftyJSON使用 SwiftyJSON 将 JSON 解析为结构
【发布时间】: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。在您的情况下,只需将ThreadsThreadDetailCodable 一致,就应该相当简单。

标签: swift alamofire swifty-json


【解决方案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

    这是您使用 Wea​​ve 的上述代码:

    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 并尝试转换为结构。

      【讨论】:

        猜你喜欢
        • 2017-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多