cellForRowAt
требует, чтобы вы возвращали ячейку синхронно.
Настройте свою ячейку, передав ответственность каждой отдельной ячейки за загрузку ее содержимого , основываясь на запросе - таким образом перезагрузив свой собственный пользовательский интерфейс.
Для иллюстрации:
Это будет ваша ячейка (с уже подключенными розетками):
class FilesManagerCell: UITableViewCell {
@IBOutlet private weak var filenameLabel: UILabel!
@IBOutlet private weak var createdDateLabel: UILabel!
@IBOutlet private weak var fileSizeLabel: UILabel!
var filePath: URL! {
didSet {
fetchContents()
}
}
override func awakeFromNib() {
super.awakeFromNib()
//Here you should create the "Loading behavior", i.e:
self.filenameLabel.text = "Loading"
self.createdDateLabel.text = "Loading"
self.fileSizeLabel.text = "Loading"
}
private func fetchContents() {
APIClient.getFileInfo(patientId: filepath.lastPathComponent, onSuccess: { response in
DispatchQueue.main.async {
self.filenameLabel.text = response.file.fileName
self.createdDateLabel.text = response.file.creationDate
self.fileSizeLabel.text = response.file.fileSizeWithToken
}
}, onError: { (errorResponse, errorString) in
//Customize your error code, i.e:
DispatchQueue.main.async {
self.filenameLabel.text = "Error"
self.createdDateLabel.text = "Error"
self.fileSizeLabel.text = "Error"
}
})
}
}
И ваш tableView cellForRowAt
Реализация:
//...
var files: [URL]!
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "FilesManagerCell", for: indexPath) as? FilesManagerCell {
let currentFile = files[indexPath.row]
cell.filePath = currentFile
}
return UITableViewCell()
}
//...
РЕДАКТИРОВАТЬ: Нет проблем с передачей этой ответственности самой ячейке, но имейте в виду, что когда ячейка повторно используется , она будет вызывать новый fetchContents()
при установке свойства filePath
, таким образом, вызывая новый вызов API - но будет некоторая «несогласованность» данных, потому что, пока выборка не возвращается, у нее будет предыдущее содержимое выборки. Одним из решений этой проблемы может быть сброс в состояние «загрузка» каждый раз, когда вы устанавливаете filePath
, что-то вроде этого:
var filePath: URL! {
didSet {
// Reset the current fields
self.filenameLabel.text = "Loading"
self.createdDateLabel.text = "Loading"
self.fileSizeLabel.text = "Loading"
// And then fetch the contents
fetchContents()
}
}