skip to Main Content

I am new in swift and have implemented a tableview with url session data and it works fine except the images are not loading and sometimes the data comes late and the tableview is empty.
I put http://localhost:3000/nameofimage.png , I get my image but when in tableview it did not work

import UIKit
import Kingfisher

class BikelistViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
   

    var bikes =  [Bike]()
    
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return bikes.count
    }
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "mCellBike")
        let contentView = cell?.contentView
        let imageView = contentView?.viewWithTag(1) as! UIImageView
        let label = contentView?.viewWithTag(2) as! UILabel
        DispatchQueue.main.async {
            
            label.text = self.bikes[indexPath.row].model
            let url = URL(string: "http://localhost:3000/"+self.bikes[indexPath.row].image)
            imageView.kf.setImage(with: url)
       
        }
       
        return cell!
    }
   
    

    //passage de parametres entre les controleurs
        //cell OnclickListener
        
         func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            let bike = bikes[indexPath.row]
            performSegue(withIdentifier: "mBikeDetails" , sender: bike) //passage de variable locale)
            
        }
        
        /* prepare est pour passer les parametres  */
        override func prepare(for segue: UIStoryboardSegue, sender: Any?){
        
        if segue.identifier == "mBikeDetails" {
        
        let bike = sender as! Bike
        let destination = segue.destination as! BikeDetailsViewController
            destination.id = bike.bike_id
            destination.model = bike.model
            destination.type = bike.type
            destination.mprice = bike.price
            destination.image = bike.image
            
        
        }}
    


    override func viewDidLoad() {
        super.viewDidLoad()

        //get
      
       guard let url = URL(string: "http://localhost:3000/bikes") else {
       return
       }
       let session = URLSession.shared
       session.dataTask(with: url)  { ( data , response ,error) in
           if let response = response {
               print(response)
           }
           
           if let data = data {
               print(data)
               do
               {
                let json = try JSONSerialization.jsonObject(with: data, options: []) as! [[String:Any]]
                self.bikes.removeAll()
                
                for item in json {
                    let id = item["bike_id"] as! Int
                    let model = item["model"] as! String
                    let type = item["type"] as! String
                    let price = item["price"] as! String
                    let image = item["image"] as! String
                    self.bikes.append(Bike(id: id,model: model,type: type,price: price,image: image))
                }
                for item in self.bikes {
                    print(item.image)
                    print("http://localhost:3000/"+item.image)
                    
                }
                print(self.bikes)
               }catch{
                   print(error)
               }
            
           }
           
       }.resume()
       
        
        // Do any additional setup after loading the view.
    }
    


}
 

I am trying to make my images load in my tableview , my data is displaying except my images. and sometimes the data comes late and the tableview is empty
Is there anything I am missing here?

2

Answers


  1. You are trying to fetch the data in main thread that is why it is lagging. Just let the main thread create cell objects, dont implement any network action here so this is wrong in your code :

    imageView.image = UIImage(named: "http://localhost:3000/"+bikes[indexPath.row].image)
    

    You should not do network actions in your main thread. If you wish either you can use use third party library such as KingFisher or using your assets folder directly. Your tableview will be relax if you do it like this:

    imageView.image = UIImage(named: "happy_bikeimage_coming_from_assets_folder")
    

    For example fetching data background :

    DispatchQueue.global(qos: .userInitiated).async {
        if let url = URL(string: urlString) {
            if let data = try? Data(contentsOf: url) {
                self.parse(json: data)
                return
            }
        }
    }
    
    Login or Signup to reply.
  2. You can use kingFisher if you are loading the image online check this:
    https://stackoverflow.com/a/65114085/14437411

    or you can use it in your assets folder and call the image by its name normally :

    DispatchQueue.main.async {
         UIImage(named: "imageName.extension")
    }
       
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search