У меня есть несколько вызовов API, которые будут обновлять uitableview всякий раз, когда они получают результаты. Пользовательский интерфейс необходимо обновлять по мере того, как API предоставляет данные. Все вызовы API являются асинхронными. Данные должны быть заполнены в правильном порядке. API0 должен обновить раздел 0, API1 должен обновить раздел 1 и так далее.
Мне удалось добиться этого с помощью двух API, но когда я использую третий API, у меня возникают сбои.
Пожалуйста, найдите мой код ниже:
@IBOutlet weak var myTableView: UITableView!
var myDataSource: myTableDataSource!
var initialLoad = true
var tablD = [Int : [Any]]()
let queue = DispatchQueue(
label: "com.affluvar.multipleAPI.MyQueue", // 1
attributes: .concurrent)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
myTableView.tableFooterView = UIView()
API0()
API1()
API2()
}
//MARK: API methods
func API0(){
queue.async {
print("queue THREAD0????")
getData(offset: 0,limit: 10){
(finalArray) in
print("IN FIRST????")
for rest in finalArray{
print(rest.name)
}
self.queue.sync {
self.tablD.updateValue(finalArray, forKey: 0)
self.myDataSource = myTableDataSource(data: self.tablD)
print("SYNC DATASOURCE UPDATED 0????")
DispatchQueue.main.async {
if self.initialLoad == true{
self.initialLoad = false
self.myTableView.dataSource = self.myDataSource
print("TABLE RELOADING INITIAL ????")
self.myTableView.reloadData()
}
}
self.saveData(data: finalArray, section: 0)
}
}
}
}
func API1(){
queue.async{
print("queue THREAD1 ????")
getData(offset: 10,limit: 12){
(finalArray1) in
print("IN SECOND ????")
for rest in finalArray1{
print(rest.name)
}
self.queue.sync{
self.tablD.updateValue(finalArray1, forKey: 1)
self.myDataSource = myTableDataSource(data: self.tablD)
print("SYNC DATASOURCE UPDATED 1????")
DispatchQueue.main.async {
if self.initialLoad == true{
self.initialLoad = false
self.myTableView.dataSource = self.myDataSource
print("TABLE RELOADING INITIAL ????")
self.myTableView.reloadData()
}
}
self.saveData(data: finalArray1, section: 1)
}
}
}
}
func API2(){
queue.async{
print("queue THREAD2")
getData(offset: 20,limit: 12){
(finalArray1) in
print("IN third")
for rest in finalArray1{
print(rest.name)
}
self.queue.sync{
self.tablD.updateValue(finalArray1, forKey: 2)
self.myDataSource = myTableDataSource(data: self.tablD)
print("SYNC DATASOURCE UPDATED 2")
DispatchQueue.main.async {
if self.initialLoad == true{
self.initialLoad = false
self.myTableView.dataSource = self.myDataSource
print("TABLE RELOADING INITIAL ????")
self.myTableView.reloadData()
}
}
self.saveData(data: finalArray1, section: 2)
}
}
}
}
func saveData(data:[userModel], section: Int){
print("queue THREAD barrier ????????", section)
//print("table datasrc entry:", self.myTableView.dataSource ?? "nil")
DispatchQueue.main.sync {
print("In else ????", section)
print("sections before IN ELSE",self.myTableView.numberOfSections)
self.myTableView.dataSource = self.myDataSource
//self.myTableView.reloadData()
//self.myTableView.beginUpdates()
print("reloading section number:", section)
self.myTableView.reloadSections([section], with: .automatic)
print("sections AFTER in ELSE",self.myTableView.numberOfSections)
//self.myTableView.endUpdates()
}
print("CONTINUING QUEUE WORK")
}
Выше мой код viewController.
Ошибка здесь ->
2018-08-01 16:13:14.381174+0530 docAnywhere[4299:118229] *** Assertion failure in -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3698.33.6/UITableView.m:13456 Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource is not set'
Класс источника данных таблицы ->>
class myTableDataSource: NSObject, UITableViewDataSource{
var userData = [Any]()
var tableData = [[Any]]()
var tablD = [Int : [Any]]()
init(data: [Int : [Any]]) {
tablD = data
}
//MARK: Table methods
func numberOfSections(in tableView: UITableView) -> Int {
//print("sections:", tablD.count)
return 3
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("reload in progress")
if let rows = tablD[section] as? [Any]{
return rows.count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "usersCell") as! usersCell
let rowData = tablD[indexPath.section] as! [Any]
let thisUser = rowData[indexPath.row] as? userModel// userData[indexPath.row] as? userModel
cell.userName?.text = thisUser?.name ?? ""
print("cell no", thisUser?.name ?? "", "at", indexPath.section, indexPath.row)
if (indexPath.row == (rowData.count - 1)) {
print("LAST CELL RELOAD COMPLETE HERE", indexPath.section)
}
return cell
}
}
Иногда ошибка такая: -
2018-08-01 16:47:53.467219+0530 docAnywhere[6084:147469] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete section 0, but there are only 0 sections before the update'
ПРИМЕЧАНИЕ. Он отлично работает в случае 2 вызовов API и невозможности использования группы диспетчеризации, поскольку пользовательский интерфейс необходимо обновлять, как только любой вызов API завершается и данные становятся доступными. Несколько массивов или источников данных нельзя использовать для нескольких API.