Search code examples
jsonswift3alamofireswifty-jsonimageurl

Displaying JSON imageURL into UITableView using Alamofire and SwiftyJSON


I am currently trying to display the JSON data on to my UITableView. I've created a separate class which handles and declares the data being extracted from the API. I also created a custom cell to display the data. However I am not sure how to display the images of the API. I was able to display the title of the API using just a standard TableViewController without custom cells:

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

    cell.textLabel?.text = recipes = [indexPath.row].title

    return cell
}

but when trying to create a custom cell the image uses an imageURL which works differently. Other tutorials and demo don't seem to be using Alamofire and SwiftyJSON.

I did read the documentation: https://github.com/SwiftyJSON/SwiftyJSON#integration but still not sure how to solve this issue. Please tell me how you'd get the API data to display on my table.

Class

import Foundation
import SwiftyJSON

    class Recipe {

        var title: String!
        var image: URL?


        init(json: JSON) {
            self.title = json["title"].stringValue
            self.image = json["image"].url

        }


    }

CustomCell

import UIKit

class RecipeCell: UITableViewCell {


    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var imgView: UIImageView?



    override func awakeFromNib() {
        super.awakeFromNib()

        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

ViewController

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view, typically from a nib.
    Alamofire.request(searchURL, method: .get, parameters: params, encoding: URLEncoding.default, headers: headers).response { [unowned self] response in
        guard let data = response.data else { return }
        let json = JSON(data: data)

        for recipe in json.arrayValue {
            let newRecipe = Recipe(json: recipe)
            self.recipes.append(newRecipe)


        }

        for recipe in self.recipes {
            print(recipe.title)
            print(recipe.image)

        }



    }


}

// Display JSON Data into the tableView

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

}

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

    // What to write here?

    return cell
}

Thank you in advance! :)


Solution

  • for this you have to make the extension of Imageview as

    extension UIImageView {
        func downloadedFrom(url: URL, contentMode mode: UIViewContentMode = .scaleAspectFit) {
            contentMode = mode
            URLSession.shared.dataTask(with: url) { (data, response, error) in
                guard
                    let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
                    let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
                    let data = data, error == nil,
                    let image = UIImage(data: data)
                    else { return }
                DispatchQueue.main.async() { () -> Void in
                    self.image = image
                }
                }.resume()
        }
        func downloadedFrom(link: String, contentMode mode: UIViewContentMode = .scaleAspectFit) {
            guard let url = URL(string: link) else { return }
            downloadedFrom(url: url, contentMode: mode)
        }
     }
    

    then you have to write cellForRowAt method as

      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "recipeCell", for: indexPath)
        let recipe = recipes[indexPath.row]
        let imagePath = recipe.image
        cell.titleLabel.text = recipe.title
        cell. imgView.downloadedFrom(link: imagePath)
    
            return cell
        }