Перезагрузите UITableView после обработки HTTP-запроса - PullRequest
0 голосов
/ 12 февраля 2019

Допустим, у меня есть два класса: один класс представляет базу данных, в которой я выполняю HTTP-запрос GET.

func getObjects(completion: (([Object]) -> Void)?) {

  guard let url = // ...

  let session = URLSession(configuration: .default)
    let task = session.dataTask(with: url) { (data, response, error) in
      DispatchQueue.main.async {
        if let error = error {
          fatalError("Dispatching main queue failed: \(error)")
        } else if let data = data {
          let decoder = JSONDecoder()

          do {
            let objects = try decoder.decode([Object].self, from: data)
            completion?(object)
          } // ...
    // ...
    }
  task.resume()
}  

Соответствующий массив объекта результата передается в UIViewController, который является другим классом.Поскольку я создаю экземпляры нескольких баз данных на основе различных объектов конфигурации, я хочу отобразить результаты, отсортированные в секционном UITableView.

func load(then: (([(DatabaseConfig?, [Object])]) -> Void)) {
  var allObjects: [(DatabaseConfig?, [Object])] = [(nil, [])]

  Storage.loadDatabaseConfigs(completion: { configs in
    self.configs = configs
  })

  for config in self.configs {
    var objectSection: (DatabaseConfig?, [Object]) = (nil, [])

    let database = Database.init(config: config)

    objectSection.0 = config
    database.getObjects(completion: { objects in
      objectSection.1.append(objects)
    })
    allObjects.append(allObjectsInSection)
  }

  then(allObjects)
}

Загрузка и «форматирование» работает.

Я называю *Функция 1009 * в viewWillAppear(), где я передаю результат в массив классов, который содержит все последние записи для TableView.Затем я пытаюсь перезагрузить данные.

override func viewWillAppear(_ animated: Bool) {
  super.viewWillAppear(true)
    self.load(then: { objects in
      self.allObjects = objects
      self.tableView.reloadData()
    })
}

Я знаю, что запрос GET требует своего времени, поэтому мой вопрос: Как или где мне перезагрузить UITableView? Я, очевидно, должен быть уверен, что запрос GET был успешно выполнен, и перезагрузить после этого.Я уже пытался вызвать DispatchQueue.main.async для перезагрузки, но это не сработало.

1 Ответ

0 голосов
/ 12 февраля 2019

Поскольку вы делаете несколько запросов, вы действительно не хотите вызывать ваше закрытие then, пока все запросы не будут завершены.Вероятно, вы могли бы использовать DispatchGroup для этого.

func load(then: (([(DatabaseConfig?, [Object])]) -> Void)) {
    var allObjects: [(DatabaseConfig?, [Object])] = [(nil, [])]

    Storage.loadDatabaseConfigs(completion: { configs in
        self.configs = configs

        let dispatchGroup = DispatchGroup()
        for config in self.configs {
            dispatchGroup.enter()
            var objectSection: (DatabaseConfig?, [Object]) = (nil, [])

            let database = Database.init(config: config)

            objectSection.0 = config
            database.getObjects(completion: { objects in
                objectSection.1.append(objects)
                dispatchGroup.leave()
            })
            allObjects.append(allObjectsInSection)
        }
        dispatchGroup.notify(queue: .main) {
            then(allObjects)
        }
    })
}

РЕДАКТИРОВАТЬ: Как отметил @Macistador, loadDatabaseConfigs является асинхронным, поэтому вызовы базы данных должны выполняться в обратном вызове completion этой функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...