My class was tasked with making an app that implements RESTful API calls. My app has 2 screens:
- The first screen that lists all the Pokemon types (in the form of parsed JSON)
- The second screen that lists details (in the form of parsed JSON) about the selected type
In our writeup for the project, we are tasked with indicating a code snippet with the "background thread." I'm not sure where the "background thread" is located in my code.
I found this StackOverflow answer, which indicates that code within DispatchQueue.global(qos: .background).async {}
is run in the background thread while code within DispatchQueue.main.async {}
is run in the main thread. However, I only have DispatchQueue.main.async {}
and no DispatchQueue.global(qos: .background).async {}
. Does this mean I have no background thread? Do I now have to implement it? Or is everything that is not in the main thread, running in the background thread by default?
The code for ViewController.swift, which lists all the Pokemon types, is below:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
final let url = URL(string: "https://pokeapi.co/api/v2/type/")
private var results = [Movetype]()
@IBOutlet var tableView: UITableView!
var sequeIdentifiers = ["Normal", "Fighting", "Flying", "Poison", "Ground", "Rock", "Bug", "Ghost", "Steel", "Fire", "Water", "Grass", "Electric", "Psychic", "Ice", "Dragon", "Dark", "Fairy", "Unknown", "Shadow"]
override func viewDidLoad() {
super.viewDidLoad()
downloadJson()
// Do any additional setup after loading the view, typically from a nib.
}
func downloadJson() {
guard let downloadURL = url else { return }
URLSession.shared.dataTask(with: downloadURL) { data, urlResponse, error in
guard let data = data, error == nil, urlResponse != nil else {
print("something is wrong")
return
}
print("downloaded")
do
{
let decoder = JSONDecoder()
let downloaded_movetypes = try decoder.decode(Results.self, from: data)
self.results = downloaded_movetypes.results
DispatchQueue.main.async { // <- ********* MAIN THREAD *********
self.tableView.reloadData()
}
} catch {
print("something wrong after downloaded")
}
}.resume()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return results.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "MovetypeCell") as? MovetypeCell else { return UITableViewCell() }
cell.Name_Label.text = results[indexPath.row].name.capitalized
let img_name = sequeIdentifiers[indexPath.row].lowercased() + ".png"
print(img_name)
cell.Img_View.image = UIImage(named: img_name)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//performSegue(withIdentifier: sequeIdentifiers[indexPath.row], sender: self)
let detailVc = self.storyboard?.instantiateViewController(withIdentifier: "Fighting") as! Fighting
detailVc.subType = sequeIdentifiers[indexPath.row].lowercased()
self.navigationController?.pushViewController(detailVc, animated: true)
}
}
Which part of that is the background thread?
The code for my app's second screen, Fighting.swift, which lists the details about the selected type, is below:
var subType = ""
override func viewDidLoad() {
super.viewDidLoad()
self.title = subType.capitalized
let jsonUrlString = "https://pokeapi.co/api/v2/type/\(subType)/"
guard let url = URL(string: jsonUrlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else { return }
do {
// Get fighting JSON data
let fighting_json = try JSONDecoder().decode(fighting.self, from: data)
let detail_json = try JSONDecoder().decode(detailData.self, from: data)
print("Codementor == \(detail_json.damage_relations)")
print(fighting_json.damage_relations?.double_damage_from?.compactMap({ $0.name?.capitalized }) ?? "Bad data")
// Create Array: Double Damage From
let double_damage_from_fighting_array = fighting_json.damage_relations?.double_damage_from?.compactMap({ $0.name?.capitalized }) ?? ["Bad data"]
// Create Array: Double Damage To
let double_damage_to_fighting_array = fighting_json.damage_relations?.double_damage_to?.compactMap({ $0.name?.capitalized }) ?? ["Bad data"]
// Create Array: Half Damage From
let half_damage_from_fighting_array = fighting_json.damage_relations?.half_damage_from?.compactMap({ $0.name?.capitalized }) ?? ["Bad data"]
// Create Array: Half Damage To
let half_damage_to_fighting_array = fighting_json.damage_relations?.half_damage_to?.compactMap({ $0.name?.capitalized }) ?? ["Bad data"]
// Create Array: No Damage From
let no_damage_from_fighting_array = fighting_json.damage_relations?.no_damage_from?.compactMap({ $0.name?.capitalized }) ?? ["Bad data"]
// Create Array: No Damage To
let no_damage_to_fighting_array = fighting_json.damage_relations?.no_damage_to?.compactMap({ $0.name?.capitalized }) ?? ["Bad data"]
DispatchQueue.main.async { // <- ***** MAIN THREAD ******
// Print Label: Double Damage From
self.double_damage_from_fighting_Label.text = double_damage_from_fighting_array.joined(separator: ", ")
// Print Label: Double Damage To
self.double_damage_to_fighting_Label.text = double_damage_to_fighting_array.joined(separator: ", ")
// Print Label: Half Damage From
self.half_damage_from_fighting_Label.text = half_damage_from_fighting_array.joined(separator: ", ")
// Print Label: Half Damage To
self.half_damage_to_fighting_Label.text = half_damage_to_fighting_array.joined(separator: ", ")
// Print Label: No Damage From
self.no_damage_from_fighting_Label.text = no_damage_from_fighting_array.joined(separator: ", ")
// Print Label: No Damage To
self.no_damage_to_fighting_Label.text = no_damage_to_fighting_array.joined(separator: ", ")
}
} catch let jsonErr {
print("Error serializing json:", jsonErr)
}
}.resume()
}
}
Which part of that code is the background thread?
I know that you typically only need to call the main thread when changing the UI. Does that mean everything in the do{}
statements in my examples is in the background thread, except for the code within DispatchQueue.main.async {}
?