Swift 4-URL会议
我在解析网站www.adx.ae上的API时遇到了一个小问题 以下是两个API: 1-所有上市公司名单: 2-各公司ID的详细信息: 我们所要做的就是根据每家公司的ID来获取其最新交易价格。。。等等 我的目标是在tableView中列出名称和每家公司的交易价格 到目前为止,这就是我所做的Swift 4-URL会议,swift,urlsession,Swift,Urlsession,我在解析网站www.adx.ae上的API时遇到了一个小问题 以下是两个API: 1-所有上市公司名单: 2-各公司ID的详细信息: 我们所要做的就是根据每家公司的ID来获取其最新交易价格。。。等等 我的目标是在tableView中列出名称和每家公司的交易价格 到目前为止,这就是我所做的 import UIKit class ViewController: UITableViewController { func getPrice(company: [Company]) {
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放在那里也不能解决问题
我在这里遗漏了什么吗?当您创建controller类时,allCompanies数组会显示UITableView将有多少行,因为它是空的(不是0),所以会崩溃。将“numberOfRowsInSection”更改为以下代码
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if(allCompanies.count == 0)
{
return 0
}else{
return allCompanies.count
}
}
对于获取价格,您将allCompanies数组发送到fetchPrice函数,但在函数为空时执行此操作。取公司后,可以调用fetchPrice函数。另外,print(prices)打印空数组,因为网络请求是异步的,但您打印时不等待应答
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时,我都会将字符串附加到prices数组中。现在它覆盖了单元格的常规文本。然而,你可以在任何你想写的地方写。这将是更好的方法,而不是等待所有请求完成
得到价格函数
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()
}
此外,;
此代码可以工作,但我建议您为此类操作编写一个网络层,并将它们从控制器类中移动。
dataTask(with:)
是异步的。这是你似乎错过的。如果您希望在重新加载数据之前完成所有调用,请使用dispatch_组(带有enter、leave和notify)。@Larme您能提供一些可能适用的示例吗?嗨,Emre,谢谢您的评论。显示AllCompanys没有问题,但我无法使用其ID查看其价格。您想何时获取价格?点击表格单元格后?应在应用程序启动后立即进行(ViewDidLoad后)。然而,如果我在上面的代码中实现getPrice方法,我就什么也得不到了,我为您的问题添加了答案。我试过了,可以成功地打印价格。请检查另外的部分:)我尝试了你的编辑,但我无法得到价格。getPrice函数中的print(Price)返回一个空数组。