无法从其余 API 获取数据以在 ViewDidLoad 上加载
Can't get data from rest API to load on ViewDidLoad
我是 swift 的新手,我无法解决这个问题。
我可以成功地从 API 获取 JSON,但是 Table 视图上的数据只有在我单击按钮后才会加载。在应用程序打开时,在 viewDidLoad 上调用相同的函数不会加载数据。
我尝试了很多解决方案,但我找不到问题出在哪里
这是主视图控制器代码:
import UIKit
struct ExpenseItem: Decodable {
let name: String
let amount: String
let id: String
let timestamp: String
let description: String
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBAction func fetchData(_ sender: Any) {
ds()
self.eTW.reloadData()
}
@IBOutlet weak var eTW: UITableView!
var allExpenses = [ExpenseItem]()
let expensesURL = "https://temp.cuttons.com/json/expenses.json"
override func viewDidLoad() {
super.viewDidLoad()
eTW.delegate = self
eTW.dataSource = self
ds()
self.eTW.reloadData()
}
func parseJSON(data: Data) -> [ExpenseItem] {
var e = [ExpenseItem]()
let decoder = JSONDecoder()
do {
e = try decoder.decode([ExpenseItem].self, from: data)
} catch {
print(error.localizedDescription)
}
return e
}
func ds() {
if let url = URL(string: expensesURL){
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, session, error) in
if error != nil {
print("some error happened")
} else {
if let content = data {
self.allExpenses = self.parseJSON(data: content)
}
}
}
task.resume()
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.allExpenses.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = eTW.dequeueReusableCell(withIdentifier: "expense", for: indexPath) as! myCellTableViewCell
cell.name.text = self.allExpenses[indexPath.row].name
if let am = Double(self.allExpenses[indexPath.row].amount) {
if (am > 0) {
cell.amount.textColor = .green
} else {
cell.amount.textColor = .red
}
}
cell.amount.text = self.allExpenses[indexPath.row].amount
return cell
}
谢谢
L.
您必须在 异步接收数据后 重新加载 table 视图。
删除viewDidLoad
中的行
override func viewDidLoad() {
super.viewDidLoad()
eTW.delegate = self
eTW.dataSource = self
ds()
}
并添加到ds
func ds() {
if let url = URL(string: expensesURL) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if let error = error {
print("some error happened", error)
} else {
self.allExpenses = self.parseJSON(data: data!)
DispatchQueue.main.async {
self.eTW.reloadData()
}
}
}
task.resume()
}
}
在 viewDidLoad()
中调用 api 后不要重新加载数据。在将 JSON 解析为您需要的对象后,在完成块内执行此操作(假设它像您说的那样成功)。
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, session, error) in
guard error == nil else {
print("some error happened")
return
}
guard let data = data else {
print("bad JSON")
return
}
self.allExpenses = self.parseJSON(data: data)
DispatchQueue.main.async {
self.eTW.reloadData()
}
}
task.resume()
此外,如果可能,请使用 guard let
而不是 if let
。
我是 swift 的新手,我无法解决这个问题。 我可以成功地从 API 获取 JSON,但是 Table 视图上的数据只有在我单击按钮后才会加载。在应用程序打开时,在 viewDidLoad 上调用相同的函数不会加载数据。 我尝试了很多解决方案,但我找不到问题出在哪里 这是主视图控制器代码:
import UIKit
struct ExpenseItem: Decodable {
let name: String
let amount: String
let id: String
let timestamp: String
let description: String
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBAction func fetchData(_ sender: Any) {
ds()
self.eTW.reloadData()
}
@IBOutlet weak var eTW: UITableView!
var allExpenses = [ExpenseItem]()
let expensesURL = "https://temp.cuttons.com/json/expenses.json"
override func viewDidLoad() {
super.viewDidLoad()
eTW.delegate = self
eTW.dataSource = self
ds()
self.eTW.reloadData()
}
func parseJSON(data: Data) -> [ExpenseItem] {
var e = [ExpenseItem]()
let decoder = JSONDecoder()
do {
e = try decoder.decode([ExpenseItem].self, from: data)
} catch {
print(error.localizedDescription)
}
return e
}
func ds() {
if let url = URL(string: expensesURL){
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, session, error) in
if error != nil {
print("some error happened")
} else {
if let content = data {
self.allExpenses = self.parseJSON(data: content)
}
}
}
task.resume()
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.allExpenses.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = eTW.dequeueReusableCell(withIdentifier: "expense", for: indexPath) as! myCellTableViewCell
cell.name.text = self.allExpenses[indexPath.row].name
if let am = Double(self.allExpenses[indexPath.row].amount) {
if (am > 0) {
cell.amount.textColor = .green
} else {
cell.amount.textColor = .red
}
}
cell.amount.text = self.allExpenses[indexPath.row].amount
return cell
}
谢谢 L.
您必须在 异步接收数据后 重新加载 table 视图。
删除viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
eTW.delegate = self
eTW.dataSource = self
ds()
}
并添加到ds
func ds() {
if let url = URL(string: expensesURL) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if let error = error {
print("some error happened", error)
} else {
self.allExpenses = self.parseJSON(data: data!)
DispatchQueue.main.async {
self.eTW.reloadData()
}
}
}
task.resume()
}
}
在 viewDidLoad()
中调用 api 后不要重新加载数据。在将 JSON 解析为您需要的对象后,在完成块内执行此操作(假设它像您说的那样成功)。
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, session, error) in
guard error == nil else {
print("some error happened")
return
}
guard let data = data else {
print("bad JSON")
return
}
self.allExpenses = self.parseJSON(data: data)
DispatchQueue.main.async {
self.eTW.reloadData()
}
}
task.resume()
此外,如果可能,请使用 guard let
而不是 if let
。