我正在尝试在我解析来自URL的JSON数据的异步任务后更新我的tableView,我正在学习Swift,我不明白这段代码有什么问题。消息是一个字符串数组,我在每个json对象中附加一个message_body。我正在等待执行HTTP请求的任务来调用方法finishedLoading,我尝试在tableView中插入行。我收到此错误'Invalid update: invalid number of rows in section 0.'
感谢您的帮助
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
cell.textLabel?.text = messages[indexPath.row]
return cell
}
func finishedLoading(array: Array<String>) {
TableView.beginUpdates()
TableView.insertRows(at: [IndexPath(row: messages.count-1, section: 0)], with: .automatic)
TableView.endUpdates()
TableView.reloadData()
}
public func init_chat()
{
var request = URLRequest(url: URL(string: "URL")!)
request.httpMethod = "GET"
let session = URLSession.shared
session.dataTask(with: request) {data, response, err in
let json = try! JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any]
let data = json?["data"] as? [[String: Any]]
for message in data! {
if let name = message["message_body"] as? String {
self.messages.append(name)
}
}
self.finishedLoading(array: self.messages)
}.resume()
}
答案 0 :(得分:1)
你有几个问题。
messages
)。messages
数组,但之后您只需添加一行就可以处理插入内容。insertRows
和reloadData
。只能打电话给其中一个。beginUpdates/endUpdates
即可使用insert/delete/reloadRowsAt
。要解决问题1,请将调用包裹在finishedLoading
内的DispatchQueue.main.async
:
DispatchQueue.main.async {
self.finishedLoading(array: self.messages)
}
解决问题2和3更复杂。首先创建一个本地数组来收集新数据。然后将该数组传递给finishedLoading
。然后更新finishedLoading
以将新数组附加到messages
并正确地通知表视图所有这些新行。
以下是解决所有问题的更新代码。
func finishedLoading(array: [String]) {
let currentCount = messages.count
messages.append(contentsOf: array)
var newPaths = [IndexPath]()
for row in 0..<array.count {
newPaths.append(IndexPath(row: row+currentCount, section: 0))
}
TableView.insertRows(at: newPaths, with: .automatic)
}
public func init_chat()
{
var request = URLRequest(url: URL(string: "URL")!)
request.httpMethod = "GET"
let session = URLSession.shared
session.dataTask(with: request) {data, response, err in
if let data = data {
let json = try! JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
if let data = json?["data"] as? [[String: Any]] {
var newData = [String]()
for message in data {
if let name = message["message_body"] as? String {
newData.append(name)
}
}
if !newData.isEmpty() {
DispatchQueue.main.async {
self.finishedLoading(array: newData)
}
}
}
}
}.resume()
}
我将其留作练习以摆脱try!
的使用,并将其替换为正确的do/catch/try
。
免责声明:上述代码尚未经过测试。可能存在拼写错误。
答案 1 :(得分:1)
添加此功能:
func numberOfRows(inSection section: Int) -> Int {
return messages.count
}
并替换此代码:
self.finishedLoading(array: self.messages)
使用此代码:
DispatchQueue.main.async {
self.tableView.reloadData()
}