UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Day 39: Course code throws warning "-[UINavigationController tabBarItem] must be used from main thread only"

Forums > 100 Days of Swift

https://www.hackingwithswift.com/read/9/5/easy-gcd-using-performselectorinbackground

The end of project 9 separates the fetchJSON code into an objc function and you call it in viewDidLoad with:

override func viewDidLoad() {
  performSelector(inBackground: #selector(fetchJSON), with: nil)
}

    @objc func fetchJSON() {
        let urlSting: String
         if navigationController?.tabBarItem.tag == 0 { 
            urlSting = "https://www.hackingwithswift.com/samples/petitions-1.json"
        } else {
            urlSting = "https://api.whitehouse.gov/v1/petitions.json?signatureCountFloor=10000&limit=100"
        }

        if let url = URL(string: urlSting)  {
            if let data = try? Data(contentsOf: url){
                parse(json: data)
                return
            }
        }
        performSelector(onMainThread: #selector(showError), with: nil, waitUntilDone: false)
    }

This throws the warning: "-[UINavigationController tabBarItem] must be used from main thread only" on

navigationController?.tabBarItem.tag == 0

My quick solution was:

override func viewDidLoad() {

      let urlString: String
      if navigationController?.tabBarItem.tag == 0 {
           urlString = "https://www.hackingwithswift.com/samples/petitions-1.json"
        } else {
            urlString = "https://api.whitehouse.gov/v1/petitions.json?signatureCountFloor=10000&limit=100"
        }

        DispatchQueue.global(qos: .userInteractive).async{ [weak self] in
            if let url = URL(string: urlString){
                if let data = try? Data(contentsOf: url){
                    self?.parse(json: data)
                    return
                }
            }
            DispatchQueue.main.async { [weak self] in
                self?.showError()
            }
        }
}

3      

Use DispatchQueue.main.async { } around if navigationController.... The compiler complains because the navigation controller is a UI component, and those must be accessed from the main thread.

3      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.