我是否正确实现了 tableviewdatasource 以获取要显示的下载数据?
Am I implementing the tableviewdatasource correctly to get downloaded data to show?
我正在开发一个小应用程序来连接到我的网站,通过 PHP 网络服务下载数据,并在 table 视图中显示。开始之前,我遵循了 Jose Ortiz Costa (Article on Medium) 在 Medium 上的教程。
我调整了他的项目并获得了它 运行 验证 Web 服务是否正常工作并且能够获取数据。一旦我开始工作,我就开始了一个新项目,并尝试引入一些我需要进行网络连接的代码,并试图让它显示在同一场景的 table 视图中,而不是弹出窗口像何塞项目的场景。
这是我 运行 遇到一些问题的地方,因为我对 swift 编程语言还很陌生(开始了 Udemy 课程并一直在从中学习)它显示在 table 视图中。我可以看到请求仍在 sent/received,但我无法让它出现在 table 视图中(使用我的自定义 XIB 或以编程方式创建的单元格)。我以为我了解代码是如何分解的,甚至尝试通过 Viewcontroller.
的扩展将它从 UITableViewController 转换为 UITableviewDataSource
在这一点上,我很困惑,将继续检查代码并调整我认为可能是根本原因的内容。非常感谢任何有关如何修复的指示!
Main Storyboard Screenshot
用于解码我的数据的结构/Lead class:
import Foundation
struct Lead: Decodable {
var id: Int
var name: String
var program: String
var stage: String
var lastAction: String
}
class LeadModel {
weak var delegate: Downloadable?
let networkModel = Network()
func downloadLeads(parameters: [String: Any], url: String) {
let request = networkModel.request(parameters: parameters, url: url)
networkModel.response(request: request) { (data) in
let model = try! JSONDecoder().decode([Lead]?.self, from: data) as [Lead]?
self.delegate?.didReceiveData(data: model! as [Lead])
}
}
}
ViewController:
import UIKit
class LeadViewController: UIViewController {
// Buttons
@IBOutlet weak var newButton: UIButton!
@IBOutlet weak var firstContactButton: UIButton!
@IBOutlet weak var secondContactButton: UIButton!
@IBOutlet weak var leadTable: UITableView!
let model = LeadModel()
var models: [Lead]?
override func viewDidLoad() {
super.viewDidLoad()
//Make Buttons rounded
newButton.layer.cornerRadius = 10.0
firstContactButton.layer.cornerRadius = 10.0
secondContactButton.layer.cornerRadius = 10.0
//Delegate
model.delegate = self
}
//Send request to web service based off Buttons Name
@IBAction func findLeads(_ sender: UIButton) {
let new = sender.titleLabel?.text
let param = ["stage": new!]
print ("findLead hit")
model.downloadLeads(parameters: param, url: URLServices.leads)
}
}
extension LeadViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
print ("number of sections hit")
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
guard let _ = self.models else {
return 0
}
print ("tableView 1 hit")
return self.models!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Create an object from LeadCell
let cell = tableView.dequeueReusableCell(withIdentifier: "leadID", for: indexPath) as! LeadCell
// Lead selection
cell.leadName.text = self.models![indexPath.row].name
cell.actionName.text = self.models![indexPath.row].lastAction
cell.stageName.text = self.models![indexPath.row].stage
cell.progName.text = self.models![indexPath.row].program
print ("tableView 2 hit")
// Return the configured cell
return cell
}
}
extension LeadViewController: Downloadable {
func didReceiveData(data: Any) {
//Assign the data and refresh the table's data
DispatchQueue.main.async {
self.models = data as? [Lead]
self.leadTable.reloadData()
print ("LeadViewController Downloadable Hit")
}
}
}
编辑
因此,经过一番搜索(好吧......大量搜索),我终于找到了一篇文章,其中说我必须将 class 设置为数据源。
leadTable.dataSource = self
所以这最终起作用了(在我添加了一个原型单元格之后,我的代码中使用了标识符)。我有一个自定义的 XIB,现在无法正常工作,这是我的下一个解决点。
您加载了数据,但未使用它。首先在viewDidLoad
方法
的末尾添加如下语句
model.delegate = self
然后添加以下LeadViewController
扩展名
extension LeadViewController: Downloadable {
func dicReceiveData(data: [Lead]) {
DispatchQueue.main.async {
self.models = data
self.tableView.reloadData()
}
}
}
还有一些建议:
使用按钮标题作为网络请求参数不是一个好的做法:
let new = sender.titleLabel?.text
let param = ["stage": new!]
最好把UI和逻辑分开。您可以使用按钮的 tag
属性(您可以在情节提要中或以编程方式配置它)来检查点击了哪个按钮。
您在 LeadModel
class 中也有几个不必要的类型转换。你可以改变
let model = try! JSONDecoder().decode([Lead]?.self, from: data) as [Lead]?
self.delegate?.didReceiveData(data: model! as [Lead])
到
do {
let model = try JSONDecoder().decode([Lead].self, from: data)
self.delegate?.didReceiveData(data: model)
}
catch {}
我正在开发一个小应用程序来连接到我的网站,通过 PHP 网络服务下载数据,并在 table 视图中显示。开始之前,我遵循了 Jose Ortiz Costa (Article on Medium) 在 Medium 上的教程。
我调整了他的项目并获得了它 运行 验证 Web 服务是否正常工作并且能够获取数据。一旦我开始工作,我就开始了一个新项目,并尝试引入一些我需要进行网络连接的代码,并试图让它显示在同一场景的 table 视图中,而不是弹出窗口像何塞项目的场景。
这是我 运行 遇到一些问题的地方,因为我对 swift 编程语言还很陌生(开始了 Udemy 课程并一直在从中学习)它显示在 table 视图中。我可以看到请求仍在 sent/received,但我无法让它出现在 table 视图中(使用我的自定义 XIB 或以编程方式创建的单元格)。我以为我了解代码是如何分解的,甚至尝试通过 Viewcontroller.
的扩展将它从 UITableViewController 转换为 UITableviewDataSource在这一点上,我很困惑,将继续检查代码并调整我认为可能是根本原因的内容。非常感谢任何有关如何修复的指示!
Main Storyboard Screenshot
用于解码我的数据的结构/Lead class:
import Foundation
struct Lead: Decodable {
var id: Int
var name: String
var program: String
var stage: String
var lastAction: String
}
class LeadModel {
weak var delegate: Downloadable?
let networkModel = Network()
func downloadLeads(parameters: [String: Any], url: String) {
let request = networkModel.request(parameters: parameters, url: url)
networkModel.response(request: request) { (data) in
let model = try! JSONDecoder().decode([Lead]?.self, from: data) as [Lead]?
self.delegate?.didReceiveData(data: model! as [Lead])
}
}
}
ViewController:
import UIKit
class LeadViewController: UIViewController {
// Buttons
@IBOutlet weak var newButton: UIButton!
@IBOutlet weak var firstContactButton: UIButton!
@IBOutlet weak var secondContactButton: UIButton!
@IBOutlet weak var leadTable: UITableView!
let model = LeadModel()
var models: [Lead]?
override func viewDidLoad() {
super.viewDidLoad()
//Make Buttons rounded
newButton.layer.cornerRadius = 10.0
firstContactButton.layer.cornerRadius = 10.0
secondContactButton.layer.cornerRadius = 10.0
//Delegate
model.delegate = self
}
//Send request to web service based off Buttons Name
@IBAction func findLeads(_ sender: UIButton) {
let new = sender.titleLabel?.text
let param = ["stage": new!]
print ("findLead hit")
model.downloadLeads(parameters: param, url: URLServices.leads)
}
}
extension LeadViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
print ("number of sections hit")
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
guard let _ = self.models else {
return 0
}
print ("tableView 1 hit")
return self.models!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Create an object from LeadCell
let cell = tableView.dequeueReusableCell(withIdentifier: "leadID", for: indexPath) as! LeadCell
// Lead selection
cell.leadName.text = self.models![indexPath.row].name
cell.actionName.text = self.models![indexPath.row].lastAction
cell.stageName.text = self.models![indexPath.row].stage
cell.progName.text = self.models![indexPath.row].program
print ("tableView 2 hit")
// Return the configured cell
return cell
}
}
extension LeadViewController: Downloadable {
func didReceiveData(data: Any) {
//Assign the data and refresh the table's data
DispatchQueue.main.async {
self.models = data as? [Lead]
self.leadTable.reloadData()
print ("LeadViewController Downloadable Hit")
}
}
}
编辑
因此,经过一番搜索(好吧......大量搜索),我终于找到了一篇文章,其中说我必须将 class 设置为数据源。
leadTable.dataSource = self
所以这最终起作用了(在我添加了一个原型单元格之后,我的代码中使用了标识符)。我有一个自定义的 XIB,现在无法正常工作,这是我的下一个解决点。
您加载了数据,但未使用它。首先在viewDidLoad
方法
model.delegate = self
然后添加以下LeadViewController
扩展名
extension LeadViewController: Downloadable {
func dicReceiveData(data: [Lead]) {
DispatchQueue.main.async {
self.models = data
self.tableView.reloadData()
}
}
}
还有一些建议: 使用按钮标题作为网络请求参数不是一个好的做法:
let new = sender.titleLabel?.text
let param = ["stage": new!]
最好把UI和逻辑分开。您可以使用按钮的 tag
属性(您可以在情节提要中或以编程方式配置它)来检查点击了哪个按钮。
您在 LeadModel
class 中也有几个不必要的类型转换。你可以改变
let model = try! JSONDecoder().decode([Lead]?.self, from: data) as [Lead]?
self.delegate?.didReceiveData(data: model! as [Lead])
到
do {
let model = try JSONDecoder().decode([Lead].self, from: data)
self.delegate?.didReceiveData(data: model)
}
catch {}