Swift、URLSession、viewDidLoad、tableViewController

Swift, URLSession, viewDidLoad, tableViewController

我从来没有真正了解 异步操作的细微差别,所以一次又一次地,我感到受阻。我就是想不通。

我正在尝试进行一些非常简单的网络抓取。

我当地的排球协会有一个页面(冗长 HTML,没有响应,不适合移动设备,yaddah,yaddah,yaddah)显示分配给本赛季每场比赛的裁判。我正在尝试编写一个愚蠢的小应用程序,它将抓取该页面(没有 API,不能直接访问数据库等)并在分组 table 中显示数据。第一组将显示今天的比赛(时间、主队、客队)。第二组将展示明天的比赛。第三组显示整个赛季的比赛。

使用我在别处找到的代码,我的 viewDidLoad 加载页面,抓取数据并将其解析为数组。一旦我解析了数据,我就有了三个数组:todaytomorrowmatches,它们都是 [Match].

override func viewDidLoad() {
  super.viewDidLoad()

  let url = URL(string: urlString)!
  let request = NSMutableURLRequest(url: url)
  let task = URLSession.shared.dataTask(with: request as URLRequest) {
    data, response, error in
    if let error = error {
      print (error)
    } else {
      if let unwrappedData = data {
        // scrape, scrape, parse, parse
        matchRow = ...
        self.matches.append(matchRow)

        if matchRow.date == todaysDate {
          self.today.append(matchRow)
        } else if matchRow.date == tomorrowsDate {
          self.tomorrow.append(matchRow)
        }
      }
    }
  }
  task.resume()
}

我敢肯定任何了解异步操作的人都不会感到惊讶,我的 table 是空的。我已经检查过,我看到数据在那里并被正确解析等。但我终究无法弄清楚如何在我的 table 中获取数据。我现在的方式是,调用 numberOfSectionsnumberOfRowsInSection 时数据尚未准备好。

我在 URLSession 上找到了 Ray Wenderlich 教程,我还有一个 Udemy 课程 (Rob Percival),它构建了一个应用程序来使用网络抓取来获取天气,但在这两种情况下,应用程序都会启动并等待用户在上网获取数据之前输入。我希望我的应用程序在启动时立即获取数据,而无需用户交互。但我就是想不通我需要做哪些更改才能使这些示例适用于我的程序。

请帮忙。

一旦从 URLSession 完成块填充了数据数组,您就可以简单地重新加载表视图。你试过了吗?示例片段可能如下所示。

let task = URLSession.shared.dataTask(with: request as URLRequest) {
    data, response, error in
    if let error = error {
      print (error)
    } else {
      if let unwrappedData = data {
        // scrape, scrape, parse, parse
        matchRow = ...
        self.matches.append(matchRow)

        if matchRow.date == todaysDate {
          self.today.append(matchRow)
        } else if matchRow.date == tomorrowsDate {
          self.tomorrow.append(matchRow)
        }
      }

      DispatchQueue.main.async { [weak self] in
        self?.todayTableView.reloadData()
        self?.tomorrowTableView.reloadData()
      }

    }
  }