我应该如何使用 Alamofire 和 SwiftyJSON 解析来自 API 的 JSON 响应?

Posted

技术标签:

【中文标题】我应该如何使用 Alamofire 和 SwiftyJSON 解析来自 API 的 JSON 响应?【英文标题】:How should I go about parsing a JSON response from an API with Alamofire and SwiftyJSON? 【发布时间】:2018-08-23 17:19:00 【问题描述】:

我正在尝试使用 Alamofire 和 SwiftyJSON 从 API 解析 JSON,但在尝试访问 JSON 中的信息时遇到了麻烦。我需要简单地解析名为“ask_price”的项目的 JSON:以及“time_coinapi”,但我不确定如何管理响应,或者我是否必须使用不同的方法。这是我目前拥有的:

class CoinAPIManager 

var prices: [String] = []
var times: [String] = []


static let shared = CoinAPIManager()

func getReq() 

    let headers: HTTPHeaders = [
        "X-CoinAPI-Key": "Key"
    ]


    Alamofire.request("https://rest.coinapi.io/v1/quotes/BITSTAMP_SPOT_BTC_USD/history?time_start=2018-08-21T00:00:00&time_end=2018-08-22T00:00:00&limit=100", headers: headers).responseJSON  response in
        debugPrint(response)

        if let data = try? String(contentsOf: response) 
            let json = JSON(parseJSON: data)


            parse(json: json)


        







    func parse(json: JSON) 
        for result in json[].arrayValue 
            let price = result["ask_price"].stringValue


        

    



我也试过这个:

func getReq() 

    let headers: HTTPHeaders = [
        "X-CoinAPI-Key": "Key"
    ]


    Alamofire.request("https://rest.coinapi.io/v1/quotes/BITSTAMP_SPOT_BTC_USD/history?time_start=2018-08-21T00:00:00&time_end=2018-08-22T00:00:00&limit=100", headers: headers).responseJSON  response in
        debugPrint(response)

        switch response.result 
        case .failure(let error):
            // Do whatever here
            return

        case .success(let data):
            // First make sure you got back a dictionary if that's what you expect
            guard let json = data as? [String : AnyObject] else 
                print("Failed to get expected response from webserver.")
                return
            

            // Then make sure you get the actual key/value types you expect
            guard var price = json["ask_price"] as? Double else 
                    print("Failed to get data from webserver")
                    return
            




我做错了什么?这是 JSON 的外观:

[
  
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"ask_price": 770.000000000,
"ask_size": 3252,
"bid_price": 760,
"bid_size": 124
  ,
  
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"time_exchange": "2013-09-28T22:40:50.0000000",
"time_coinapi": "2017-03-18T22:42:21.3763342",
"ask_price": 770.000000000,
"ask_size": 3252,
"bid_price": 760,
"bid_size": 124
  
]

上一个问题因大错而被删除并重新发布

【问题讨论】:

仅供参考 - 不要使用多个第三方库,而是使用提供的工具 - URLSession 和 JSONDecoder。 【参考方案1】:

您需要像这样更改对 SwiftyJSON 对象的响应

Alamofire.request("https://rest.coinapi.io/v1/quotes/BITSTAMP_SPOT_BTC_USD/history?time_start=2018-08-21T00:00:00&time_end=2018-08-22T00:00:00&limit=100", headers: headers).responseJSON  response in
        debugPrint(response)

        switch response.result 
        case .failure(let error):
            // Do whatever here
            return

        case .success:
            // First make sure you got back a dictionary if that's what you expect
                let responseJSON = JSON(response.result.value!)
                if responseJSON.count != 0 
                    print(responseJSON)
                    //do whatever you want with your object json
                
        

我建议在你的 ApiManager 中你可以使用完成块来管理异步请求,检查下一个代码。

  class func getRequestWithoutParams(didSuccess:@escaping (_ message: JSON) -> Void, didFail: @escaping (_ alert:UIAlertController)->Void)



    Alamofire.request("http://foo.bar"),method: .post,parameters: parameters,encoding: JSONEncoding.default,headers:nil).responseJSON  response in
                switch response.result
                case .success:
                    let res = JSON(response.result.value!)
                    didSuccess(res)
                    break
                case .failure(let error):
                    let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
                    let done = UIAlertAction(title: "OK", style: .default, handler: nil)
                    alert.addAction(done)
                    didFail(alert)
                
            


【讨论】:

【参考方案2】:

从 Swift 4 开始,你应该可以使用codable 来解决它:

struct YourStructure: Codable 

   let symbol_id: String?
   let time_exchange: String?
   let ask_price: String?

   private enum CodingKeys: String, CodingKey 
     case symbol_id = "symbol_id"
     case time_exchange = "time_exchange"
     case ask_price = "ask_price"
    

然后用JSONDecoder解析它

let decoder = JSONDecoder()
let parsedData = decoder.decode(YourStructure.self, from: "YourJsonData")

【讨论】:

以上是关于我应该如何使用 Alamofire 和 SwiftyJSON 解析来自 API 的 JSON 响应?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Alamofire Swift iOS 中将 Origin 传递给 Header?

如何使用 Swift 3 将单例与 Alamofire 一起使用?

如何使用 AlamoFire 和 Swift 将 JSON 数据放入 UILabel

如何使用 Alamofire 和 Swift Decode 从 JSON 解码和访问 Double

Swift 使用 Alamofire 和 SwiftyJSON 解析 Json [关闭]

如何使用 Alamofire (Swift 2.2) 获取 Twitter 访问令牌