Reputation: 921
I am getting 'MBProgressHUD needs to be accessed on the main thread.' error on hiding MBProgressHUD once page is loaded with data from web service. Please help me to solve this. Stuck on this issue since hours now. My code is :
DispatchQueue.main.async {
self.spinnerActivity.hide(animated: true)
self.tableView.reloadData()
self.refreshControl.endRefreshing()
}
I started the spinner in viewDidLoad as follows :
spinnerActivity = MBProgressHUD.showAdded(to: self.view, animated: true);
spinnerActivity.label.text = "Loading";
spinnerActivity.detailsLabel.text = "Please Wait!!";
Please help.
Edit:
This is my whole code of that view controller :
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
var refreshControl: UIRefreshControl!
var spinnerActivity: MBProgressHUD! = nil
override func viewDidLoad() {
super.viewDidLoad()
refreshControl = UIRefreshControl()
refreshControl.tintColor = UIColor.green
refreshControl.attributedTitle = NSAttributedString(string: "Refreshing", attributes: [NSForegroundColorAttributeName: UIColor.white])
refreshControl.addTarget(self, action: #selector(ViewController.refresh(sender:)), for: UIControlEvents.valueChanged)
tableView.addSubview(refreshControl)
spinnerActivity = MBProgressHUD.showAdded(to: self.view, animated: true);
spinnerActivity.label.text = "Loading";
spinnerActivity.detailsLabel.text = "Please Wait!!";
self.navigationItem.hidesBackButton = true
let newBackButton = UIBarButtonItem(title: "Back", style: UIBarButtonItemStyle.plain, target: self, action: #selector(ViewController.back(sender:)))
self.navigationItem.leftBarButtonItem = newBackButton
navigationItem.title = city.uppercased()
self.runWebService()
}
func runWebService(){
let url = URL(string: "")!// have removed my url
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in // URLSession.shared().dataTask(with: url) { (data, response, error) is now URLSession.shared.dataTask(with: url) { (data, response, error)
if error != nil {
self.spinnerActivity.hide(animated: true)
print(error)
} else {
if let urlContent = data {
do {
guard let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as? [AnyObject] else {
self.spinnerActivity.hide(animated: true)
return
}
//processing web service
//DispatchQueue.global(qos: .userInitiated).async {
DispatchQueue.main.async {
self.spinnerActivity.hide(animated: true)
self.tableView.reloadData()
self.refreshControl.endRefreshing()
}
} catch {
self.spinnerActivity.hide(animated: true)
print("JSON Processing Failed")
}
}
}
}
task.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func back(sender: UIBarButtonItem) {
_ = navigationController?.popToRootViewController(animated: true)
}
func refresh(sender:AnyObject) {
//pull to refresh
self.runWebService()
}
//remaining are table view data source and delegate methods }
Upvotes: 1
Views: 3713
Reputation: 2916
You're trying to hide the MBProgressHUD from the background in all of your error handling. Switch over to the main thread to fix:
func runWebService(){
let url = URL(string: "http://www.google.com")!// have removed my url
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in // URLSession.shared().dataTask(with: url) { (data, response, error) is now URLSession.shared.dataTask(with: url) { (data, response, error)
if error != nil {
DispatchQueue.main.async {
self.spinnerActivity.hide(animated: true)
}
print(error)
} else {
if let urlContent = data {
do {
guard let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as? [AnyObject] else {
DispatchQueue.main.async {
self.spinnerActivity.hide(animated: true)
}
return
}
//processing web service
//DispatchQueue.global(qos: .userInitiated).async {
DispatchQueue.main.async {
self.spinnerActivity.hide(animated: true)
}
} catch {
DispatchQueue.main.async {
self.spinnerActivity.hide(animated: true)
}
print("JSON Processing Failed")
}
}
}
}
task.resume()
}
** Note that I removed some of your code to test.
Upvotes: 2