Не удалось использовать JSON данных в расширении viewController? - PullRequest
0 голосов
/ 09 января 2020

Может кто-нибудь, пожалуйста, дайте мне знать, что я здесь не так сделал? Я не смог передать данные JSON из URLSession.shared.dataTask во внешнее расширение. Также я не смог доставить удовольствие c numberOfSections .. et c для использования в URLSession.shared.dataTask

Любая помощь приветствуется, спасибо за ваше время.

Swift

struct getSubData: Decodable {let id: Int let name: String}

struct Раздел: Decodable {let id : Int let name: String let subData: [getSubData]}

class indexViewController: UIViewController {@IBOutlet слабый var tableView: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()
    let url = "https://nabulsi.com/nabulsi_app/main_sections_v4.json"
                         let urlObj = URL(string: url)
                         URLSession.shared.dataTask(with: urlObj!){(data, response, error) in
                             do {
                                 let sections = try JSONDecoder().decode([Section].self, from: data!)
                                for section in sections {
                                    print(section.name)
                                    let sectionName = section.name
                                    for data in section.subData {
                                        print(data.name)
                                        let subSectionName = data.name
                                    }
                                }
                             } catch {
                                 print("We got an error")
                             }
                         }.resume()
}

}

расширение indexViewController : UITableViewDataSource, UITableViewDelegate {

func numberOfSections(in tableView: UITableView) -> Int {
    return sectionName.count

}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return sectionName[section].subSectionName?.count ?? 0

}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
    cell.textLabel?.text = sectionName[indexPath.section].subSectionName?[indexPath.row]

    return cell
}

}

Ответы [ 2 ]

1 голос
/ 10 января 2020

Класс JsonDecoder не имеет возможности анализировать ваши данные только из-за полученного JSON текста с сервера не является допустимым форматом .

Здесь конечную точку, откройте ее в веб-браузере: https://nabulsi.com/nabulsi_app/main_sections_v4.json

А вот инструмент проверки JSON: https://jsonlint.com

Скопируйте и вставьте, чтобы проверить ответ сервера на инструмент проверки JSON с именем jsonlint , и вы увидите, в чем ваша ошибка ,

Возможно, это не твоя вина. Речь идет о вашем бэкэнд-разработчике, если вы не писали сами. Свяжитесь с ним, чтобы исправить формат JSON. После устранения проблемы, пожалуйста, сообщите мне. Я исправлю ваши коды разбора, если они все еще не работают так, как вы ожидали.

  • РЕДАКТИРОВАТЬ: После устранения проблемы, соответствующие коды здесь:

[0] - Parsed json значения, присвоенные локальной переменной.

class indexViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var sections: [Section] = []

override func viewDidLoad() {
    super.viewDidLoad()
    let url = "https://nabulsi.com/nabulsi_app/main_sections_v4.json"
    let urlObj = URL(string: url)
    URLSession.shared.dataTask(with: urlObj!){(data, response, error) in
        do {
            let sections = try JSONDecoder().decode([Section].self, from: data!)
            self.sections = sections // [0]

            DispatchQueue.main.async {
                self.tableView.reloadData()
            }

        } catch {
            print("We got an error")
        }
    }.resume()
  }
}
  • Посмотрите на код и следуйте этим кратким объяснениям:

[1] - Возвращать все строки в разделе из локального массива

[2] - Назначена переменная имени для метки для текущей строки

[3] - Назначена переменная имени для заголовка для текущей секции

extension indexViewController: UITableViewDataSource, UITableViewDelegate {

func numberOfSections(in tableView: UITableView) -> Int {
    return sections.count
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let subDatas = sections[section].subData // [1]
    return subDatas.count ?? 0
}



func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

    // [2]
    let currentSection = sections[indexPath.section]
    let currentSubdata = currentSection.subData[indexPath.row]
    cell.textLabel?.text = currentSubdata.name

    return cell
}


func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 40))
    view.backgroundColor = #colorLiteral(red: 1, green: 0.3653766513, blue: 0.1507387459, alpha: 1)

    let lbl = UILabel(frame: CGRect(x: 0, y: 0, width: view.frame.width - 15, height: 40))
    lbl.font = UIFont.systemFont(ofSize: 20)
    lbl.text = sections[section].name // [3]
    lbl.textAlignment = .right
    view.addSubview(lbl)

    return view
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 40
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 40
  }
}

Happy Coding! =]

0 голосов
/ 09 января 2020

Просто возьмите секцию Array за пределы вашей функции. Сохраните его как собственность вашего контроллера.

class indexViewController: UIViewController { 

  @IBOutlet weak var tableView: UITableView!
  var sections: [Section] = []

  override func viewDidLoad() {
    super.viewDidLoad()

    let url = "https://nabulsi.com/nabulsi_app/main_sections_v4.json"
    let urlObj = URL(string: url)
    URLSession.shared.dataTask(with: urlObj!) {
     [weak self](data, response, error) in
     do {
          self?.sections = try JSONDecoder().decode([Section].self, from: data!)
          for section in sections {
            //your code goes here                         
          }
    } 
    catch {
      print("We got an error")
    }
  }.resume()
}
...