Image Caching
Image Caching with AlamofireImage
We constructed an application in the last portion of this tutorial that required us to download an image from a URL (provided by an API) and place it in the picture view. Nevertheless, we used the following code in the tableview DataSource method to download every image in real time.
cell.artistImgView.image = try UIImage(data: Data(contentsOf: URL(string: artistData.artworkUrl60!) ?? URL(string: "http://www.google.com")!))
Observing that application, we find that because the image is being downloaded via the main thread, scrolling through the tableview has been a very time-consuming job. But if we continue to download and configure the picture from a runtime image URL, the problem will still exist.
We can utilize AlamofireImage to fix this problem because it makes the process of downloading images easier. Here, we can use it to download an image and then use NSCache to add the downloaded picture to the cache at the same time.
Setup
Since AlamofireImage operates on top of Alamofire, installing both of these libraries is required in order to use AlamofireImage. By adding the following line to our Podfile, we can use it to install AlamofireImage.
pod ' AlamofireImage '
We may import AlamofireImage using the import statement in swift when the pod installation is finished.
import Alamofire
import AlamofireImage
The following code needs to be used to build up the cache before we can use AlamofireImage to download the images.
let imageCache = AutoPurgingImageCache( memoryCapacity: 111_111_111, preferredMemoryUsageAfterPurge: 90_000_000)
We must now make a download request for the image. We make use of Alamofire’s request mechanism for this.
Alamofire.request(self.nameUrl[i]).responseImage { response in
if response.result.value != nil {
let image = UIImage(data: response.data!, scale: 1.0)! imageCache.add(image, withIdentifier: self.nameUrl[i]) } }
We must fetch the image from the cache while adding it to the image view because we added it to the image cache.
if let image = imageCache.image(withIdentifier: self.nameUrl[self.a]){
self.localImageView.image = image
}
Example
We will now carry on with the ArtistProject that we started in the earlier portion of this guide. This time, though, we’ll use the image cache to store all of the photos we plan to load into the tableview and use it to load the images.
We will, however, be altering the ViewController.swift file. The other project files won’t change at all.
ViewController.swift
import UIKit
import Alamofire
import AlamofireImage
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var artist = Array()
let imageCache = AutoPurgingImageCache(memoryCapacity: 111_111_111, preferredMemoryUsageAfterPurge: 90_000_000)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
loadJsonData()
tableView.delegate = self
tableView.dataSource = self
//tableView.rowHeight = UITableView.automaticDimension
}
func loadJsonData()
{
Alamofire.request("https://itunes.apple.com/search?media=music&term=bollywood").responseJSON { (response) in
//print("Response value \(response)")
do{
if(response.result.isSuccess){
let result: ArtistResponseModel = try JSONDecoder().decode(ArtistResponseModel.self, from: response.data!)
debugPrint(result)
self.artist = result.results ?? []
for i in result.results ?? []{
Alamofire.request(i.artworkUrl60!).responseImage { (response) in
if response.result.value != nil{
let image = UIImage(data: response.data!, scale: 1.0)
self.imageCache.add(image!, withIdentifier: i.artworkUrl60! )
}
}
}
self.tableView.reloadData()
}
}catch{
}
}
}
}
extension ViewController : UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return artist.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MainTableViewCell") as! MainTableViewCell
if(artist.count > 0){
let artistData = artist[indexPath.row]
cell.artistImgView.image = imageCache.image(withIdentifier: artistData.artworkUrl60!)
cell.trackName.text = artistData.trackName
cell.artisName.text = artistData.artistName
cell.artistCountry.text = artistData.country
}
return cell
}
}
extension ViewController : UITableViewDelegate{
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 220
}
}
Now that the project is running, scrolling will be seamless because the images are being retrieved from the cache rather than downloaded during runtime.