Best place to make network calls
ios, lifecycle, swift, uiviewcontroller
Solution
Requests need to be fired in the `viewWillAppear:`, only this method notifies you that the screen is about to be shown. If you don't want to send requests every time the screen is shown, consider caching the data once you have it.
`viewDidLoad` is not the best candidate. It has nothing to do with the appearance of the screen. It's called right after a view controller's view is requested for the first time, not when the screen is showing up.
For example, if the screen was destroyed (by popping from a navigation controller), you'll receive `viewDidLoad` when you show it again (by pushing the screen to the navigation controller). Or if the app receives a memory warning, a current view is unloaded and loaded again, which ends up sending the view controller `viewDidLoad`.
`viewDidLoad` is tricky.
If you think that `viewDidLoad` will save you from fetching the data from the server multiple times: sometimes it will, sometimes it won't. Anyway, it's not the right tool to optimize networking, caching is!
Since remote requests are expensive (they take time and traffic), you want to understand when are they sent. `viewWillAppear:` gives you understanding. And in conjunction with caching you can make it optimal.
UPDATE
In most cases, it's not a good idea to send requests from the view controller directly. I would suggest creating a separate networking layer.
Problem
Network Call :- ``` static func getProfile(parameters:[String:AnyObject], onComplete:[String:AnyObject]->()) { var requiredData:[String:AnyObject] = [:] Alamofire.request(.GET,API.getProfile,parameters: parameters).validate().responseJSON { (response) in if let responseData = response.result.value { if let jsonData = responseData as? [String:AnyObject] { requiredData["UserName"] = jsonData["UName"] requiredData["UserEmail"] = jsonData["UEmail"] requiredData["UserMobileNo"] = jsonData["UPhone"] requiredData["UserAddress"] = jsonData["UAddress"] requiredData["UserCity"] = jsonData["UCity"] }// Inner If } // Main if onComplete(requiredData) }// Alamofire Closed }// Func closed ``` Network Call within required VC :- ``` override func viewDidLoad() { super.viewDidLoad() let parameters:[String:AnyObject] = [ "WebKey": API.WebKey.value.rawValue, "UId":NSUserDefaults.standardUserDefaults().integerForKey("UserId") ] NetworkInterface.getProfile(parameters) { (responseDictionary) in //print("Passed Data \(responseDictionary["UserName"])") self.userData = responseDictionary self.updateUI() } } ``` As far as i know, VC Lifecycle is somewhat as follows :- init(coder aDecoder:NSCoder) -> viewDidLoad -> viewWillAppear -> viewWillDisappear However, Even after view appears it takes few seconds for user Information to be displayed in those textfields. I thought viewDidLoad is the best place to make network calls. I understand that network calls are async so it will take time to fetch required data from network and respond. However, network call was made in viewDidLoad so by the time view will appear, it should already have required data ? Should it not ? So can anyone explain me which is the best place to make network calls and why? I want textfields to be updated with user Info as soon as view Appears.