Search code examples
swiftlistviewalamofireswifty-jsonviewdidload

Cannot use parsed data on list view


I am making JSON requests and getting some response from api, and i am parsing it but, priority is a problem for me.

First i send .post with alamofire,

second i get some response and parsing it with swiftyjson

Third trying to use parsed data on list view but listview works first before parse and returns empty listview

I tried putting function first line in viewdidload, I tried write Alamofire and swiftyjson part in viewdidload.

but none of them worked, everytime listviews numberofrowinsection function work first.

I couldnt use my helper class or any static variable with this because, i am holding credit card data and i dont want to make some security issues with this.

import UIKit
import CreditCardForm
import Alamofire
import SwiftyJSON

class CreditCardScreen: UIViewController, UITableViewDelegate , UITableViewDataSource {
    var json: JSON = []
    var data: JSON = []
    var token: Parameters = [
        "token": Helper.token,
        "page_index": "0",
        "page_size": "20"
    ]


    @IBOutlet weak var creditCardTableView: UITableView!
    @IBOutlet weak var creditCardView: CreditCardFormView!


    override func viewDidLoad() {
        super.viewDidLoad()
        getCreditCardsFromApi()
        creditCardView.isHidden = true
        creditCardTableView.delegate = self
        creditCardTableView.dataSource = self
        creditCardTableView.separatorStyle = .none


        //creditCardView.changer(value:"10/20")

        // Do any additional setup after loading the view.
    }

    @IBAction func unCreditCardScreen(_ sender: UIStoryboardSegue) {
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.data.count // everytime this line works before than api parsing
    }

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


        let cell = Bundle.main.loadNibNamed("CreditCardIndexPage", owner: self, options: nil)?.first as! CreditCardIndexPage

        let selectedCard = data[indexPath.row]
        cell.cardHolderName = selectedCard["card_name"].stringValue
        //cell.cardHolderName = isimler[indexPath.row]
        cell.cardNumber = "4242424242424240"
        cell.backgroundColor = UIColor.clear
        cell.write()
        return cell


    }
    func getCreditCardsFromApi(){
        Alamofire.request("\(Helper.mainApi)/api/getPaymentCards", method: .post, parameters: token, encoding: JSONEncoding.default).responseJSON{response in
            switch response.result{
            case .success(let value):
                self.json = JSON(value)
                self.data = self.json["data"]




            case .failure(let error):
                print(error.localizedDescription)

            }
        }

}


}

There is no error messages but i tried to see which one is working first with break points, always tableview function works after declare variable.


Solution

  • HTTP requests take time. They can't possibly finish before the table view is loaded. The right way to do this is to reload the table view when you've got the data:

    func getCreditCardsFromApi(){
        Alamofire.request("\(Helper.mainApi)/api/getPaymentCards", method: .post, parameters: token, encoding: JSONEncoding.default).responseJSON{response in
            switch response.result{
            case .success(let value):
                self.json = JSON(value)
                self.data = self.json["data"]
                self.tableView.reloadData() <--- this line!
    
            case .failure(let error):
                print(error.localizedDescription)
    
            }
        }
    

    numberOfCellsInSection will still be called first, but it will be called a second time after you have received the response.