可解码结构 JSON

structure for Decodable JSON

我正在尝试将以下 API link 放入 Swift

中的 Decodable JSON

Link Here

下面是映射 link:

的代码
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: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.})))

谢谢

Post 编辑:

当我 运行 在单独的 class 调用服务中的以下函数时出现错误:

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()

}
}

在ViewControllerclass中,上述函数将如下:

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

    }


}




}

你的结构的唯一问题是 JSON:

中存在这种东西
{"Price":null,"Shares":null}

为了解决这个问题,您需要重写 Order 结构以允许空值:

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
}