Не удается получить данные из API остальных для загрузки на ViewDidLoad - PullRequest
0 голосов
/ 13 апреля 2020

Я новичок в Свифте и не могу разобраться с этой проблемой. Я могу успешно сделать JSON выборку из API, но данные в табличном представлении загружаются только после нажатия кнопки. Вызов той же функции для viewDidLoad не загружал данные при открытии приложения. Я перепробовал множество решений, но не могу найти причину ошибки. Вот код контроллера основного вида:

import UIKit

struct ExpenseItem: Decodable {
    let name: String
    let amount: String
    let id: String
    let timestamp: String
    let description: String
}

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBAction func fetchData(_ sender: Any) {
        ds()
        self.eTW.reloadData()
    }

    @IBOutlet weak var eTW: UITableView!

    var allExpenses = [ExpenseItem]()
    let expensesURL = "https://temp.cuttons.com/json/expenses.json"

    override func viewDidLoad() {
        super.viewDidLoad()
        eTW.delegate = self
        eTW.dataSource = self
        ds()
        self.eTW.reloadData()
    }

    func parseJSON(data: Data) -> [ExpenseItem] {
        var e = [ExpenseItem]()
        let decoder = JSONDecoder()
        do {
            e = try decoder.decode([ExpenseItem].self, from: data)

        } catch {
            print(error.localizedDescription)
            }
            return e
        }


    func ds()  {
        if let url = URL(string: expensesURL){
            let session = URLSession(configuration: .default)
            let task = session.dataTask(with: url) { (data, session, error) in
                if error != nil {
                    print("some error happened")
                } else {
                    if let content = data {
                        self.allExpenses = self.parseJSON(data: content)

                    }
                }
            }
            task.resume()
        }
    }

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

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

        let cell = eTW.dequeueReusableCell(withIdentifier: "expense", for: indexPath) as! myCellTableViewCell
        cell.name.text = self.allExpenses[indexPath.row].name
        if let am = Double(self.allExpenses[indexPath.row].amount) {
            if (am > 0) {
                cell.amount.textColor = .green
            } else {
                cell.amount.textColor = .red
            }
        }
        cell.amount.text = self.allExpenses[indexPath.row].amount
        return cell
    }

спасибо L.

Ответы [ 2 ]

0 голосов
/ 13 апреля 2020

Не перезагружать данные после вызова API в viewDidLoad(). Сделайте это внутри блока завершения после разбора JSON на нужный вам объект (если он успешен, как вы сказали).

let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, session, error) in
    guard error == nil else {
        print("some error happened")
        return 
    }

    guard let data = data else { 
        print("bad JSON")
        return 
    }
    self.allExpenses = self.parseJSON(data: data)
    DispatchQueue.main.async {
        self.eTW.reloadData()
    }
}
task.resume()

Также, если возможно, используйте guard let вместо if let .

0 голосов
/ 13 апреля 2020

Необходимо перезагрузить представление таблицы после асинхронного получения данных.

Удалить строку в viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()
    eTW.delegate = self
    eTW.dataSource = self
    ds()
}

и добавить ее в ds

func ds()  {
    if let url = URL(string: expensesURL) {
        let session = URLSession(configuration: .default)
        let task = session.dataTask(with: url) { (data, response, error) in
            if let error = error {
                print("some error happened", error)
            } else {
                self.allExpenses = self.parseJSON(data: data!)
                DispatchQueue.main.async {
                    self.eTW.reloadData()
                }
            }
        }
        task.resume()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...