我在网站上解析API时有一个小问题www.adx.ae
这是两个API:
1-所有上市公司列表:https://www.adx.ae/en/_vti_bin/adx/svc/members.svc/listedcompanies?showprivate=false&
2-每个公司的详细信息,都通过其ID:https://www.adx.ae/en/_vti_bin/adx/svc/trading.svc/listedcompanyorderbook?listedcompanyid = adib
我们要做的就是根据每家公司的ID机会,以获取其最新的交易价格...等等。
我的目的是在表观视图中列出名称和每个公司的交易价格。
到目前为止,这就是我所做的
import UIKit
class ViewController: UITableViewController {
func getPrice(company: [Company]) {
var price = [String]()
let companyLink = "https://www.adx.ae/en/_vti_bin/ADX/svc/trading.svc/ListedCompanyOrderBook?listedCompanyID="
for comp in company {
let link = companyLink + comp.ID
guard let url = URL(string: link) else { return }
URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
guard let dataResult = data else { return }
do {
let company = try JSONDecoder().decode(SpecificCompany.self, from: dataResult)
DispatchQueue.main.async {
price.append(String(company.LastTradePrice))
self.tableView.reloadData()
}
} catch {
print(error)
}
}).resume()
}
print(price)
allPrices = price
}
struct Company: Decodable {
let Name: String
let ID: String
var link: String {
get {
return "https://www.adx.ae/en/_vti_bin/ADX/svc/trading.svc/ListedCompanyOrderBook?listedCompanyID=" + ID
}
}
}
struct SpecificCompany: Decodable {
let LastTradePrice: Double
}
var allCompanies = [Company]()
var allPrices = [String]()
override func viewDidLoad() {
super.viewDidLoad()
getCompanies()
}
func getCompanies() {
let link = "https://www.adx.ae/en/_vti_bin/adx/svc/Members.svc/ListedCompanies?showPrivate=false&showPublic=true"
guard let url = URL(string: link) else { return print("Error") }
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let obtainedData = data else { return print("No data")}
do {
let adx = try JSONDecoder().decode([Company].self, from: obtainedData)
DispatchQueue.main.async {
self.allCompanies = adx
self.tableView.reloadData()
}
} catch {
print("Nothing")
print(error)
}
}.resume()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return allCompanies.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = allCompanies[indexPath.row].ID
cell.detailTextLabel?.text = allPrices[indexPath.row]
return cell
}
}
我无法获得我想要的阵列中的价格。在调用CellForrowat Indexpath的功能之前,AllCompanies数组似乎是空的!即使将函数置于getPrice也无法解决问题。
我在这里错过了什么吗?
创建控制器类时,它看起来allCompanies数组以获取uiTableView拥有多少行,并且因为它是空的(不是0(,所以它崩溃了。使用以下代码更改" numberFrowsInsection"。
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(allCompanies.count == 0)
{
return 0
}else{
return allCompanies.count
}
}
以获取价格,您将AllCompanies阵列发送到FetchPrice功能,但是当它空为空时,您正在这样做。在公司获取公司后,您可以调用FetchPrice功能。此外,打印(价格(打印空数组,因为网络请求是异步的,但是您正在打印而不等待答案。
func getCompanies() {
let link = "https://www.adx.ae/en/_vti_bin/adx/svc/Members.svc/ListedCompanies?showPrivate=false&showPublic=true"
guard let url = URL(string: link) else { return print("Error") }
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let obtainedData = data else { return print("No data")}
do {
let adx = try JSONDecoder().decode([Company].self, from: obtainedData)
DispatchQueue.main.async {
self.allCompanies = adx
self.tableView.reloadData()
self.getPrice(company: self.allCompanies)
}
} catch {
print("Nothing")
print(error)
}
}.resume()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = allCompanies[indexPath.row].ID
if(allPrices.count != 0 && allPrices.count > indexPath.row){
cell.textLabel?.text = allPrices[indexPath.row]
}
return cell
}
编辑2:每次请求完成并刷新TableView时,我将字符串附加到价格数组。现在它覆盖了一个通常的单元文本。但是,您可以在想要的任何地方写下它。这将是更好的方法,而不是等待所有请求完成。
获取价格功能;
var allPrices = [String]()
func getPrice(company: [Company]) {
let companyLink = "https://www.adx.ae/en/_vti_bin/ADX/svc/trading.svc/ListedCompanyOrderBook?listedCompanyID="
for comp in company {
let link = companyLink + comp.ID
guard let url = URL(string: link) else { return }
URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
guard let dataResult = data else { return }
do {
let company = try JSONDecoder().decode(SpecificCompany.self, from: dataResult)
DispatchQueue.main.async {
self.allPrices.append(String(company.LastTradePrice))
self.tableView.reloadData()
print(self.allPrices)
}
} catch {
print(error)
}
}).resume()
}
self.tableView.reloadData()
}
另外;此代码将起作用,但我建议您为这种操作编写网络层,并将其从控制器类中移动。