Ios Swift-URLSession任务中的TableView数据源

Ios Swift-URLSession任务中的TableView数据源,ios,swift,uitableview,asynchronous,Ios,Swift,Uitableview,Asynchronous,我必须用URLSession任务获取的一些数据填充TableView。源代码是一个XML文件,因此我将其解析为任务。解析的结果是一个数组,我将它传递给另一个函数,该函数填充了TableView委托使用的另一个数组 func checkInstalledApps(apps: NSMutableArray){ .... installedApps.add(...) installedApps.add(...) .... } 我的问题是任务结束前会调用

我必须用
URLSession任务获取的一些数据填充
TableView
。源代码是一个XML文件,因此我将其解析为任务。解析的结果是一个数组,我将它传递给另一个函数,该函数填充了
TableView委托使用的另一个数组

    func checkInstalledApps(apps: NSMutableArray){
    ....
    installedApps.add(...)
    installedApps.add(...)
    ....
    }
我的问题是任务结束前会调用
TableView委托
,因此启动应用程序时该表为空,除非重新加载数据(因此我知道解析和任务工作正常)

这里是
viewDidLoad
函数
listOfApps
是我的
TableView

    override func viewDidLoad() {

            super.viewDidLoad() 

            fetchData()
            checkInstalledApps(apps: <ARRAY POPULATED>)  

            listOfApps.delegate = self
            listOfApps.dataSource = self

        }
    }
checkInstalledApps
是我组成
TableView委托使用的数组的函数

    func checkInstalledApps(apps: NSMutableArray){
    ....
    installedApps.add(...)
    installedApps.add(...)
    ....
    }
因此,例如,要设置我计数的行数
installedApps
元素

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if (installedApps.count == 0) {
        noApp = true
        return 1
    }
    return installedApps.count
}
那是0。显然,如果我重新加载数据,一切正常

我的问题是异步调用:首先,我使用了一个可通过GET请求访问的XML,因此我可以使用
XMLParser(contentsOf:myUrl)
,时间不是问题。也许如果XML能够成熟起来,我也会遇到一些麻烦,但现在我不得不使用POST请求

我已尝试使用
DispatchGroup
,使用了

  • group.enter()
    super.viewDidLoad
  • group.leave()
    task.resume()之后
  • group.wait()
    after
    checkInstalledApps()
其中group为
让group=DispatchGroup()
,但不包含任何内容

那么,我如何告诉tableview委托等待任务响应和下一个函数呢


提前感谢

我会忘记
DispatchGroup
,并改变这里的思维方式(在收到响应之前,您不想冻结UI)

我相信您可以让
fetchData
实现保持原样

XMLParserDelegate.parserdenddocument(:)
中,将通知您XML已被解析。在该方法中,调用
选中InstalledApps
,以填充模型数据。之后,只需调用
listOfApps.reloadData()
,告诉tableView使用新数据重新加载

您希望在主线程上调用
checkInstalledApps
listOfApps.reloadData()
(使用
DispatchQueue.main.async{}


同时保持
listOfApps.delegate=self
listOfApps.dataSource=self
viewDidLoad
中保持现在的状态。

更干净的方法是使用空状态视图/activityIndicator/loader/progress hud(无论您想要什么),通知用户应用程序正在获取/加载数据


获取完成后,只需重新加载tableview并删除空的状态视图/加载程序即可。您的问题是因为您目前无法知道
URLSession
任务何时结束。
reloadData()

下面是发生的情况的简化图:

完成块在这里提供了一个易于实现的解决方案。下面是一个非常简单的解决方案(可能不完整,因为我没有关于实际xml解析的所有细节):

func fetchData(completion: @escaping () -> Void) {
     let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in
            self.parser = XMLParser(data: data!)
            self.parser.delegate = self
            completion()
}

override func viewDidLoad() {
    super.viewDidLoad() 
    fetchData() { [weak self] in self?.tableView.reloadData() }
}
基本上,完成块将完成xml数据返回链