Reputation: 3336
So, on my app I have a feed that I want to update every time the user returns to the app.
I'm calling a routine to do this on applicationWillEnterForeground
of my AppDelegate
.
Everything is working fine but, sometimes, my UI freezes during this operation.
I was able to find where this occurs using a label to show the progress of this routine. The label is updated on three major points:
Sometimes, this workflow works fine, and I'm able to see the progress through this label. But sometimes, the label only shows the first message, and messages that happen inside the routine does not appear. Besides that, I can't do anything on my app, because the UI is frozen. Once the routine is over, everything comes back to normal.
Here's a simplified version of the flow my app executes to call this routine:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
let mainViewController = MainViewController()
func applicationWillEnterForeground(_ application: UIApplication) {
mainViewController.refreshLatestVideos()
}
}
class MainViewController: UITabBarController {
private var subscriptionsController: SubscriptionsController! // initialized on viewDidLoad
func refreshLatestVideos() {
subscriptionsController.refreshLatestVideos(sender: nil)
}
}
class SubscriptionsController: UITableViewController {
private var subscriptionsModelController: SubscriptionsModelController! // received on constructor
@objc func refreshLatestVideos(sender:UIButton!) {
showMessage(message: "Updating subscriptions...") // this message is always shown to me
subscriptionsModelController.loadLatestVideos()
}
}
class SubscriptionsModelController {
func loadLatestVideos() {
UIApplication.shared.isNetworkActivityIndicatorVisible = true
DispatchQueue.global(qos: .userInitiated).async {
// bunch of requests with Just
...
// update message
showMessage(message: "Updating subscription x of y") // this message sometimes doesn't appear, because the UI is frozen
// another requests
...
// update message
showMessage(message: "Updates completed")
}
}
}
As you can see, I'm executing the update inside the global queue, so I'm not blocking the main thread. And again, this freezing of the UI only happens sometimes.
Is there any point which I can look at to find what's going on? Is it possible that the main thread is being blocked by something else?
Upvotes: 0
Views: 2489
Reputation: 19747
Dispatch updating the UI to the main thread:
DispatchQueue.main.async { showMessage(message: "Updates completed") }
Everytime you anyhow access/modify the UI, do it on the main thread to avoid having unexpected problems (link to one of several resources on this topic, I suggest you google up and read more).
That applies to the rest of the code as well, if there is something that is related to UI, do the same for it - e.g., if after finishing the task you call tableView.reloadData
, do it on the main thread too.
Upvotes: 3