Reputation:
I am working on iOS application and came to one issue which is eating my time to understand. I can not put all source code here but I am trying to put which is related to issue.
class MyItemsListVC: UIViewController, UITableViewDataSource,UITableViewDelegate {
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
func updateMyProductList() {
//update data source array code here
dispatch_async(dispatch_get_main_queue(), { () -> Void in
productListTableView.reloadData()
})
}
}
I have one parentViewController (UIViewController) of above class which holds object of his childViewController i.e MyItemsListVC object.
Based on some business logic when I call "updateMyProductList" method from parentViewController I get below method call sequence.
Here I am expecting after 3rd step, code inside "dispatch_async" block should get call which reloads table view. I am not sure why "viewWillAppear" get called. I am OK if "viewWillAppear" get called after "dispatch_async".
Here does dispatch_async(dispatch_get_main_queue() block code is having low priority over "viewWillAppear"? since both are in Main thread?
It will be really helpful if I get some hints to solve this.
Upvotes: 1
Views: 1106
Reputation: 811
Your question is light on details, but it sounds like your asynchronous call is being returned after your viewWillAppear is called.
I would suggest moving your network code to a dedicated singleton class for handling all your network calls, then having your view load in such a way that it loads quickly and waits gracefully for new data (i.e. an activity indicator). Then when the new data returns you update the view.
Upvotes: 0
Reputation: 19
I have never written anything for iOS in that language, but from my experience I can tell you that updateMyProductList is called on the parent class not on yours, which obviously calls your viewWillAppear. :). I guess you must override updateMyProductList the same way:
override func updateMyProductList() {..}
I don't think you can get to the dispatch if your method is never called :). If it is executed after viewWillAppear you must sync them.
Upvotes: -1
Reputation: 1319
So hows the result right now? Which method call is not working? Can you specify?
My advise, you should create a separate class just for handling the data / api calls. Create a array for storing data in that class, set it to internal
so that you can access the array in other classes. Here are some code snippet that you can read.
class APIManager : NSObject {
static let sharedInstance = APIManager()
typealias NerfireAPICompletionBlock = (_ value: AnyObject?, _ error: NSError?) -> Void
internal var dataArray = Array()
internal func callServerToFetchNewData(){
//call api and store data to dataArray
if error != nil {
completion(nil, error as NSError?)
} else {
completion(true as AnyObject?, nil)
}
}
}
class MyItemsListVC: UIViewController, UITableViewDataSource,UITableViewDelegate {
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
func updateMyProductList(completion: @escaping NerfireAPICompletionBlock) {
//update data source array code here
APIManager.sharedInstance.callServerToFetchNewData(){ success, error -> Void in
if error != nil {
print(error?.description)
} else {
productListTableView.reloadData()
}
}
}
}
Upvotes: 0