【问题标题】:not able to parse the JSON using JSON decoder无法使用 JSON 解码器解析 JSON
【发布时间】:2018-03-30 05:24:47
【问题描述】:

我是 swift 新手,我正在尝试集成 CCAvenue 支付网关。我正在访问服务器以从 CCAvenue 服务器获取支付选项列表,我收到了响应,但我无法将数据解析为 JSON 对象,它引发了一些异常。提前感谢您的帮助

这是我的代码

override func viewDidLoad() {
        super.viewDidLoad()

let urlAsString = "https://test.ccavenue.com/transaction/transaction.do?"

        let myRequestString = "command=\(COMMAND)&currency=\(currency)&amount=\(amount)&access_code=\(accessCode)&customer_identifier=\(customerIdentifier)"
        let myRequestData = NSData.init(bytes: myRequestString.cString(using: .utf8), length: myRequestString.count) as Data
        let request = NSMutableURLRequest.init(url: URL(string: urlAsString)!)
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
        request.setValue(urlAsString, forHTTPHeaderField: "Referer")
        request.setValue("Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", forHTTPHeaderField: "User-Agent")
        request.httpMethod = "POST"
        request.httpBody = myRequestData

        let requestData = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in
            let responseData = NSString.init(data: data!, encoding: String.Encoding.ascii.rawValue)

            if error == nil {
                print("\(responseData)")
            }

            // if request is error free then decode the json using json decoder and assigning the values to the array
            guard let data = data  else {return}
            do{
               let a = try JSONDecoder().decode([CCPaymentOption].self, from: data)

                print("\(String(describing: a))")
            }catch {
                print("Error")
            }
            }.resume()

        print("\(requestData)")
    }

这就是我在调试器中得到的结果

Optional({"payOptions":[{"payOpt":"OPTCRDC","payOptDesc":"Credit Card","cardsList":"[{\"cardName\":\"Diners Club\",\"cardType\":\"CRDC\",\"payOptType\":\"OPTCRDC\",\"payOptDesc\":\"Credit Card\",\"dataAcceptedAt\":\"CCAvenue\",\"status\":\"ACTI\"},{\"cardName\":\"MasterCard\",\"cardType\":\"CRDC\",\"payOptType\":\"OPTCRDC\",\"payOptDesc\":\"Credit Card\",\"dataAcceptedAt\":\"CCAvenue\",\"status\":\"ACTI\",\"statusMessage\":\"\"},{\"cardName\":\"Visa\",\"cardType\":\"CRDC\",\"payOptType\":\"OPTCRDC\",\"payOptDesc\":\"Credit Card\",\"dataAcceptedAt\":\"CCAvenue\",\"status\":\"ACTI\"}]"},{"payOpt":"OPTDBCRD","payOptDesc":"Debit Card","cardsList":"[{\"cardName\":\"MasterCard Debit Card\",\"cardType\":\"DBCRD\",\"payOptType\":\"OPTDBCRD\",\"payOptDesc\":\"Debit Card\",\"dataAcceptedAt\":\"CCAvenue\",\"status\":\"ACTI\"},{\"cardName\":\"Visa Debit Card\",\"cardType\":\"DBCRD\",\"payOptType\":\"OPTDBCRD\",\"payOptDesc\":\"Debit Card\",\"dataAcceptedAt\":\"CCAvenue\",\"status\":\"ACTI\"}]"},{"payOpt":"OPTNBK","payOptDesc":"Net Banking","cardsList":"[{\"cardName\":\"AvenuesTest\",\"cardType\":\"NBK\",\"payOptType\":\"OPTNBK\",\"payOptDesc\":\"Net Banking\",\"dataAcceptedAt\":\"CCAvenue\",\"status\":\"ACTI\",\"statusMessage\":\"\"}]"}]})

错误

【问题讨论】:

  • 如果您的代码抛出异常并且您需要帮助,最好的办法是在您的问题中包含该异常。我建议你在 catch 循环中设置一个断点,与我们分享错误详情。

标签: ios swift ccavenue


【解决方案1】:

解码对象时需要检查的点很多。

  1. 确保您的 CCPaymentOption 模型添加协议可编码
  2. 在解码数据时,请确保您意识到您的响应是 DictionaryArray 的形式
  3. 假设您得到了 Array 作为响应,在这种情况下,您可以直接在 JSONDecoder().decode() 方法中使用 [CCPaymentOption] .
  4. 如果您从服务器响应中获取字典,那么您需要以这种方式解码对象。

示例 CCPaymentOption Model for point no 3

struct CCPaymentOption : Codable {
    var amount:String  // Note down that , please use exact same 
                       // key as you are getting from server side.
}

do {

       let arrPaymentOptions = try JSONDecoder().decode([CCPaymentOption].self, from: responseData)

               print(arrPaymentOptions)
               ///... Array of Your Model reference.

    } catch {
               print(error)
            }

示例 CCPaymentOption Model for point no 4

struct CCPaymentOption : Codable {
    var amount:String
}

struct responseDictionary : Codable {
    var paymentOption:[CCPaymentOption] // Note down that , please 
                                        // use exact same key as you 
                                        // are getting from server 
                                        // side.
}

do {

        let responseDict = try JSONDecoder().decode(responseDictionary.self, from: responseData)

               print(responseDict.paymentOption)
               // responseDict.paymentOption is the Array of Your 
               // Model reference.

    } catch {
               print(error)
            }

如果您不想使用 JSON 解码器,请尝试以下方法。 :-

URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in

                    guard error == nil else { return }
                    guard let responseData = data else { return }

                    do {

                        if let jsonObject = try JSONSerialization.jsonObject(with: responseData, options: []) as? [String:Any] {
                            ///... All you want is here  jsonObject is the Dictionary (required , not an optional)  
                        }

                    } catch  {
                        print(error)
                    }
                }).resume()

从服务器端获取数据后,需要借助原生方法进行JSONSerialization。此方法将返回 字典数组取决于您的服务器 响应。)

【讨论】:

  • 很高兴帮助你@Rishabh.t。
  • @GOPALVASANI & @Rishabh.t :只是想让你们都知道这个答案与JSONDecoder 无关。 JSONSerialization 会将 json 转换为字典/数组,而 JSONDecoder 会将 json 转换为您的 CCPaymentOption 模型对象。
  • @staticVoidMan ,我知道,甚至 objectMapper 都用于将数据映射到我们的模型类。
  • @GOPALVASANI 好的,但您确实意识到这个问题是关于 JSONDecoder 并且 OP 使用的是 CCPaymentOption 模型。如果您要提供替代解决方案,请在您的回答中提及,否则这个家伙会回来询问为什么他的 CCPaymentOption 模型不起作用。
  • 是的 @staticVoidMan ,好的,让我在 Json 解码器的帮助下更新答案。
猜你喜欢
  • 1970-01-01
  • 2017-10-20
  • 2020-12-02
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多