Handling Background Tasks
Handling Background Tasks
We will learn how to manage the iOS application’s background tasks in this section of the course. This section will focus on enhancing the Artist Project, an application we developed earlier in the lesson to present the Artist data to the user.
We will now employ multithreading to enhance the Artist Project’s performance. We have cached images in the Artist Project using the viewDidLoad() function on the primary thread. On the other hand, this may be done asynchronously in the background. It is important to note that all UI updating actions must always occur on the main thread.
DispatchQueue.global(qos: .background).async { [weak self] in
debugPrint("performing image caching")
guard let self = self else{
return
}
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! )
}
}
}
DispatchQueue.main.sync {
debugPrint("reloading tableview")
self.tableView.reloadData()
}
}
This will let the viewDidLoad(:) to finish before reloading the table view and caching the pictures. It is important to note that the table view is refreshed on the main thread in this instance, and that the main thread is where all UI updates must always occur.
Below is the updated ViewController.swift file.
//
// ViewController.swift
// ParseJsonData
//
// Created by Ayush Sharma on 06/08/19.
// Copyright © 2019 Apple Inc. All rights reserved.
//
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 ?? []
DispatchQueue.global(qos: .background).async { [weak self] in
debugPrint("performing image caching")
guard let self = self else{
return
}
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! )
}
}
}
DispatchQueue.main.sync {
debugPrint("reloading tableview")
self.tableView.reloadData()
}
}
}
}catch{
}
}
debugPrint("end of view did load")
}
}
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]
DispatchQueue.main.async {
cell.artistImgView.image = self.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
}
}
Given that the print statement was used in the code, let’s examine the console output that is shown below.
"end of view did load" ArtistProject.ArtistResponseModel "performing image caching" "reloading tableview"