可解码JSON

时间:2018-04-02 16:12:31

标签: json swift decodable

我正在尝试将以下API链接放入Swift中的Decodable JSON

Link Here

以下是映射链接的代码:

import Foundation

struct SelectedCompany: Decodable {

    let LastTradePrice: Double
    let ListedCompanyID: String
    let ListedCompanyName: String
    let MarketTotalOrdersByOrder: Int
    let MarketTotalOrdersByPrice: Int
    let MarketTotalSharesByOrder: Int
    let MarketTotalSharesByPrice: Int
    let NumberOfTrades: Int
    let Value: Int
    let Volume: Int
    let MarketAskOrdersByOrder: [Order]
    let MarketAskOrdersByPrice: [Order]
    let MarketBidOrdersByOrder: [Order]
    let MarketBidOrdersByPrice: [Order]
    let VWAP: Int

}

struct Order: Decodable {
    let Price: Double
    let Shares: Int
}

知道为什么没有正确映射?当我尝试在模拟器中运行它时,我收到以下错误

  

dataCorrupted(Swift.DecodingError.Context(codingPath:[],debugDescription:“给定数据无效JSON。”,underlyingError:可选(错误域= NSCocoaErrorDomain Code = 3840“JSON文本未以数组或对象开头)以及允许未设置片段的选项。“UserInfo = {NSDebugDescription = JSON文本不以数组或对象开头,并且选项允许未设置片段。}))

由于

发布编辑:

当我在名为Service的单独类中运行以下函数时出现错误:

class Service {
static func getSpecificCompany(companyID: String, table: UITableView, completion: @escaping (SelectedCompany) -> ()) {

    let link = "https://www.adx.ae/en/_vti_bin/ADX/svc/trading.svc/ListedCompanyOrderBook?listedCompanyID=\(companyID)"
    guard let url = URL(string: link) else { return }

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

        guard let resultData = data else { return }

        do {
            let resultCompany = try JSONDecoder().decode(SelectedCompany.self, from: resultData)

            DispatchQueue.main.async {
                completion(resultCompany)
                table.reloadData()
            }

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

}
}

在ViewController类中,上面的函数如下:

class SomeViewController: UIViewController {

@IBOutlet weak var myTable: UITableView!

var selectedCompany:[SelectedCompany]?
var companyID = String()

override func viewDidLoad() {
    super.viewDidLoad()
    Service.getSpecificCompany(companyID: companyID, table: myTable) { (company) in
        self.selectedCompany = company

    }


}




}

1 个答案:

答案 0 :(得分:0)

你的结构的唯一问题是JSON中存在这种东西:

{"Price":null,"Shares":null}

要解决此问题,您需要重写Order结构以允许null:

struct Order: Decodable {
    let Price: Double?
    let Shares: Int?
}

一旦我这样做,我就可以使用您的SelectedCompany和Order成功解码您显示的JSON。

这是测试(成功)的游乐场代码:

let json = """
{"LastTradePrice":3.87,"ListedCompanyID":"ADIB","ListedCompanyName":"Abu Dhabi Islamic Bank","MarketAskOrdersByOrder":[{
"Price":3.87,"Shares":100000},{
"Price":3.88,"Shares":100000},{
"Price":3.88,"Shares":6000},{
"Price":3.89,"Shares":100000},{
"Price":3.9,"Shares":30000},{
"Price":3.9,"Shares":100000},{
"Price":3.98,"Shares":99800},{
"Price":3.98,"Shares":10000},{
"Price":3.99,"Shares":75000},{
"Price":3.99,"Shares":285018},{
"Price":4,"Shares":100000},{
"Price":4,"Shares":100000},{
"Price":4,"Shares":10000},{
"Price":4,"Shares":6336},{
"Price":4,"Shares":100000},{
"Price":4.09,"Shares":5000},{
"Price":4.1,"Shares":50000},{
"Price":4.11,"Shares":5000},{
"Price":4.13,"Shares":28894},{
"Price":4.13,"Shares":25000}],"MarketAskOrdersByPrice":[{
"Price":3.87,"Shares":100000},{
"Price":3.88,"Shares":106000},{
"Price":3.89,"Shares":100000},{
"Price":3.9,"Shares":130000},{
"Price":3.98,"Shares":109800},{
"Price":3.99,"Shares":360018},{
"Price":4,"Shares":316336},{
"Price":4.09,"Shares":5000},{
"Price":4.1,"Shares":50000},{
"Price":4.11,"Shares":5000},{
"Price":4.13,"Shares":53894},{
"Price":4.14,"Shares":193000},{
"Price":4.15,"Shares":85000},{
"Price":4.2,"Shares":127211},{
"Price":4.25,"Shares":250000},{
"Price":4.26,"Shares":10000}],"MarketBidOrdersByOrder":[{
"Price":3.85,"Shares":5349},{
"Price":3.85,"Shares":200000},{
"Price":3.84,"Shares":70000},{
"Price":3.84,"Shares":300000},{
"Price":3.83,"Shares":75000},{
"Price":3.81,"Shares":28000},{
"Price":3.8,"Shares":700000},{
"Price":3.79,"Shares":100000},{
"Price":3.79,"Shares":10000},{
"Price":3.72,"Shares":50000},{
"Price":3.68,"Shares":100000},{
"Price":3.67,"Shares":15000},{
"Price":3.67,"Shares":25000},{
"Price":null,"Shares":null},{
"Price":null,"Shares":null},{
"Price":null,"Shares":null},{
"Price":null,"Shares":null},{
"Price":null,"Shares":null},{
"Price":null,"Shares":null},{
"Price":null,"Shares":null}],"MarketBidOrdersByPrice":[{
"Price":3.85,"Shares":205349},{
"Price":3.84,"Shares":370000},{
"Price":3.83,"Shares":75000},{
"Price":3.81,"Shares":28000},{
"Price":3.8,"Shares":700000},{
"Price":3.79,"Shares":110000},{
"Price":3.72,"Shares":50000},{
"Price":3.68,"Shares":100000},{
"Price":3.67,"Shares":40000},{
"Price":null,"Shares":null},{
"Price":null,"Shares":null},{
"Price":null,"Shares":null},{
"Price":null,"Shares":null},{
"Price":null,"Shares":null},{
"Price":null,"Shares":null},{
"Price":null,"Shares":null}],"MarketTotalOrdersByOrder":28,"MarketTotalOrdersByPrice":16,"MarketTotalSharesByOrder":1678349,"MarketTotalSharesByPrice":1678349,"NumberOfTrades":41,"VWAP":0,"Value":7159043,"Volume":1863558}
"""

let jsondata = json.data(using: .utf8)

struct SelectedCompany: Decodable {

    let LastTradePrice: Double
    let ListedCompanyID: String
    let ListedCompanyName: String
    let MarketTotalOrdersByOrder: Int
    let MarketTotalOrdersByPrice: Int
    let MarketTotalSharesByOrder: Int
    let MarketTotalSharesByPrice: Int
    let NumberOfTrades: Int
    let Value: Int
    let Volume: Int
    let MarketAskOrdersByOrder: [Order]
    let MarketAskOrdersByPrice: [Order]
    let MarketBidOrdersByOrder: [Order]
    let MarketBidOrdersByPrice: [Order]
    let VWAP: Int

}

struct Order: Decodable {
    let Price: Double?
    let Shares: Int?
}

do {
    let result = try JSONDecoder().decode(SelectedCompany.self, from: jsondata!)
    print(result) // works fine
} catch {
    print(error) // no error
}