我對 iOS 有點陌生,正在從 GitHub API 進行網路提取,但無法在表視圖中顯示用戶。下面是代碼,
視圖控制器:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var avatarImage: UIImageView!
@IBOutlet weak var userName: UILabel!
@IBOutlet weak var usersTableView: UITableView!
var network = Network()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
network.delegate = self
usersTableView.dataSource = self
}
override func viewWillAppear(_ animated: Bool) {
network.network()
}
}
extension ViewController: NetworkDelegate {
func updateTableView() {
DispatchQueue.main.async {
self.usersTableView.reloadData()
}
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let users = network.users {
print(users.count)
return users.count
} else {
return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
print("CALLED")
let cell = tableView.dequeueReusableCell(withIdentifier: "userCell", for: indexPath) as! UserViewCell
return cell
}
}
順便說一句,識別符號來自 .xib 檔案,識別符號匹配,我不認為問題出在這里。
網路檔案
import Foundation
protocol NetworkDelegate {
func updateTableView()
}
class Network {
var users: [GitHub]?
var delegate: NetworkDelegate?
func network() {
let url = "https://api.github.com/users"
let request: URLRequest?
if let URL = URL(string: url) {
request = URLRequest(url: URL)
URLSession.shared.dataTask(with: request!) { result, response, error in
if let data = result {
// print(String(data: data, encoding: .utf8)!)
self.users = self.parseJSON(data)
self.delegate?.updateTableView()
} else {
print(error!.localizedDescription)
}
}
.resume()
}
}
private func parseJSON(_ data: Data) -> [GitHub]? {
let json = JSONDecoder()
do {
let decodedData = try json.decode([GitHub].self, from: data)
// print(decodedData)
return decodedData
} catch {
print(error.localizedDescription)
}
return nil
}
}
GitHub API 模型
struct GitHub: Codable {
let login: String
let id: Int
let node_id: String
let avatar_url: String
let gravatar_id: String
let url: String
let html_url: String
let followers_url: String
let following_url: String
let gists_url: String
let starred_url: String
let subscriptions_url: String
let organizations_url: String
let repos_url: String
let events_url: String
let received_events_url: String
let type: String
let site_admin: Bool
}
當我在模擬器上運行此代碼時,輸??出為空白(在標簽下方)

無法弄清楚我哪里做錯了
提前致謝。
uj5u.com熱心網友回復:
嘗試使用完成處理程式重構您的代碼,而不使用委托模式。
在您的network file:
enum ApiError: Error {
case network(Error)
case genericError
case httpResponseError
case invalidData
case decoding
// you can handle your specific case
}
func network(completion: @escaping ( _ error: ApiError?, _ users: [GitHub]?)-> Void) {
let url = "https://api.github.com/users"
let request: URLRequest?
if let URL = URL(string: url) {
request = URLRequest(url: URL)
URLSession.shared.dataTask(with: request!) { result, response, error in
if let error = error {
completion(.network(error), nil)
return
}
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
completion( .httpResponseError, nil)
return
}
guard let data = result else {
completion(.invalidData, nil)
return
}
do {
let decodedData = try JSONDecoder().decode([GitHub].self, from: data)
completion(nil, decodedData)
} catch {
completion(.decoding, nil)
}
}
.resume()
}
}
然后在您的 ViewController 中,您可以這樣使用它:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
network.network { [weak self] error, users in
guard let self = self else { return }
if let error = error {
print(error)
return
}
DispatchQueue.main.async {
guard let users = users else { return }
self.users = users
self.tableView.reloadData()
}
}
}
如果它仍然沒有顯示并且cellForRow沒有被呼叫,則您的約束可能有問題并且 tableView 框架為零(高度、寬度或兩者)。
嘗試在內部numberOfRowsInSection和除錯區域中除錯設定斷點,po tableView或者只是列印 tableView 并檢查寬度或高度是否為零。它可能會被呼叫幾次。第一次框架應該為零,但在某些時候你應該得到一個具有高度和寬度的框架。如果沒有,請檢查您的約束。
您可以查看我的示例,該示例具有 375 x 641 的表格視圖

uj5u.com熱心網友回復:
如果您的單元格是 xib 檔案,那么您必須使用 tableView 注冊您的單元格。
在呼叫資料源之前 viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
usersTableView(UINib(nibName: "userCell", bundle: nil), forCellReuseIdentifier: "userCell")
network.delegate = self
usersTableView.dataSource = self
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/362664.html
