继续让索引超出范围并且表格无法正确显示,可能是由于 DispatchQueue

Keep getting index out the range and the tables don't get displayed correctly, probably due to DispatchQueue

我已将其设置为每次日期选择器更改时都会在表格视图中显示新数据。我需要更改日期几次,以便让表格显示一些内容,然后它开始正确更新,但之后我一直收到 "index out of range error"。我怀疑我没有正确使用 DispatchQueue。 我的代码有什么问题?

感谢

var showNumberOfRes: Int = 0

class HomeViewController:  UIViewController, UITableViewDelegate, UITableViewDataSource {


    @IBOutlet weak var tableView: UITableView!

    var restaurants = [Results]()     

    func todaysDate() -> String {

        let date = Date()
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        let result = formatter.string(from: date)

        return result
    }

    @IBAction func datePicker(_ sender: UIDatePicker) {
        selectedDate = sender.date

    }

    var selectedDate : Date = Date() {
           didSet {
               let dateFormatter = DateFormatter()
               dateFormatter.locale = Locale(identifier: "es_ES_POSIX")
               dateFormatter.dateFormat = "yyyy-MM-dd"

             returnJson()

           }
       }

    func returnJson(){

        DispatchQueue.global(qos: .userInitiated).async {

            let formatter = DateFormatter()
           formatter.dateFormat = "yyyy-MM-dd"
            let dateSelected = formatter.string(from: self.selectedDate)

           let parameters = "{\n\t\"locale\": \”mainplace\”,\n\t\”date\": \"\(dateSelected)\",\n\t\"access_token\": \"\(token)\"\n}"
           let postData = parameters.data(using: .utf8)

           var request = URLRequest(url: URL(string: "https://somelink:18999/salesAPI/localeSales")!,timeoutInterval: Double.infinity)
           request.addValue("application/json", forHTTPHeaderField: "Content-Type")

           request.httpMethod = "POST"
           request.httpBody = postData

           let task = URLSession.shared.dataTask(with: request) { data, response, error in
               guard let data = data else {
                   print(String(describing: error))
                   return
               }
               print(String(data: data, encoding: .utf8)!)

               let decoder = JSONDecoder()

               if let jsonPetitions = try? decoder.decode(RootRequest.self, from: data) {
                   self.restaurants = jsonPetitions.results
                   showNumberOfRes = self.restaurants.count
                   print (" \(self.restaurants.count) got it from Json")

               }
               else {print("Nothing!!")}

        }

            task.resume()

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

            }

        }
    } // End Json

    func loadData() {
          tableView.reloadData()

        let defaults = UserDefaults.standard
         userNameData = defaults.string(forKey: "userNameData")!
         passwordData = defaults.string(forKey: "passwordData")!
         token = defaults.string(forKey: "enterKey")!

        returnJson()

               }

    override func viewDidLoad() {
        super.viewDidLoad()

         self.tableView.dataSource = self
         self.tableView.delegate = self

       returnJson()

    } // End of viewDidLoad

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

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        print("\(showNumberOfRes) printed in the table")
        return showNumberOfRes

    }

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

            let displayNames = restaurants[indexPath.row]

             cell.locales.text = displayNames.locale

             return cell

    }

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

        return CGFloat(80)

    }  // End Tables


}

您必须重新加载table视图数据任务的完成处理程序中。

另外两个变化:

  1. 后台队列是多余的,因为 URLSession 产生了自己的后台队列
  2. 从不在 JSONDecoder 行中 try?。抓住 error 并打印它

    func returnJson() {
    
       let formatter = DateFormatter()
       formatter.dateFormat = "yyyy-MM-dd"
       let dateSelected = formatter.string(from: self.selectedDate)
    
       let parameters = "{\n\t\"locale\": \”mainplace\”,\n\t\”date\": \"\(dateSelected)\",\n\t\"access_token\": \"\(token)\"\n}"
       let postData = parameters.data(using: .utf8)
    
       var request = URLRequest(url: URL(string: "https://somelink:18999/salesAPI/localeSales")!,timeoutInterval: Double.infinity)
       request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    
       request.httpMethod = "POST"
       request.httpBody = postData
    
       let task = URLSession.shared.dataTask(with: request) { data, response, error in
           guard let data = data else {
               print(error!)
               return
           }
           print(String(data: data, encoding: .utf8)!)
    
           let decoder = JSONDecoder()
    
           do {
               let jsonPetitions = try decoder.decode(RootRequest.self, from: data) 
               self.restaurants = jsonPetitions.results
               showNumberOfRes = self.restaurants.count
               print (" \(self.restaurants.count) got it from Json")
               DispatchQueue.main.async {
                   self.tableView.reloadData()
               }
    
           } catch {
               print(error)
           }
       }
       task.resume()
    
    } // End Json