Swift - Как вы можете установить обработчик завершения, чтобы иметь возвращаемое значение?ИЛИ Лучший способ отобразить данные из запроса API на таблицу без задержки - PullRequest
0 голосов
/ 21 декабря 2018

Я практикую звонки по API из приложения Swift, используя бесплатный Star Wars API.Сначала я попытался сделать вызов API (HTTP-запрос) внутри функции viewDidLoad ().Это сработало, за исключением того, что мне пришлось бы перейти на другую вкладку и вернуться до фактической загрузки результатов таблицы.

Поэтому я подумал, почему бы мне не выполнить вызов API (HTTP-запрос) внутри функции cellForRowAt tableView,Таким образом, данные могут появиться без задержки.Я не смог закончить это ...


import UIKit

class PeopleViewController: UIViewController {

    var people: [String] = []

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.dataSource = self
        self.tableView.delegate = self
        self.tableView.reloadData()
    }

    override func viewWillAppear(_ animated: Bool) {
        self.tableView.reloadData()
    }
}

extension PeopleViewController: UITableViewDataSource, UITableViewDelegate {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.people.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let urlRequest = URL(string: "http://swapi.co/api/people")
        let session = URLSession.shared

        let myCompletionHandler: (Data?, URLResponse?, Error?) -> Void = { (data,response,error) in
            do {
                if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary {
                    if let results = jsonResult["results"] as? [NSDictionary] {
                        for oneResult in results {
                            if let name = oneResult["name"] {
                                self.people.append((name as? String)!)
                            }
                        }
                    }
                }

                let cell = tableView.dequeueReusableCell(withIdentifier: "SWCharacterCell", for: indexPath)

                cell.textLabel?.text = self.people[indexPath.row]

                return cell

            } catch {
                print(error)
            }
        }

        let task = session.dataTask(with: urlRequest!, completionHandler: myCompletionHandler)
        task.resume()
    }
}

Я не смог закончить это, потому что httpRequest использует функцию обратного вызова (обработчик завершения), которая по умолчаниювозвращает недействительнымЯ не могу поместить «возвращаемую ячейку» внутри обработчика завершения без ошибки.

Есть ли способ добавить тип возвращаемого значения в обработчик завершения?

Я смогвместо этого сделайте httpRequest внутри функции viewDidLoad, но я пытаюсь сделать это таким образом, чтобы убедиться, что мне не нужно переключать вкладки перед тем, как увидеть данные в таблице.- Это происходит потому, что обработчик завершения не выполняется до заполнения данных таблицы.Я думаю, что, помещая запрос API внутри функции cellForRowAt во время заполнения таблицы, она будет загружаться без задержки.

Конечный результат должен выглядеть следующим образом ...

Спасибо за ваше время.

Вот ссылка на мой репозиторий Github.

...