user1949387 user1949387 - 11 days ago 5
Swift Question

IOS Swift value of an Integer is not being saved

I am learning Swift but I have a Variable (Followers) of type Int in ViewDidLoad, I set the value to a default of 0 . I then do a Json Request which returns 1 array and I set the value of Followers to whatever number it is inside the Json Array which is 788 . However when I do a Print afterwards the value keeps staying at 0. This is my code and it'll make more sense

override func viewDidLoad() {
super.viewDidLoad()
var followers = 0

// Sent HTTP Request

sessionn.dataTask(with:requestt, completionHandler: {(data, response, error) in
if error != nil {
// print(error)
} else {
do {

let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:Any]
if let Profiles = parsedData["data"] as! [AnyObject]? {

for Profiles in Profiles {

if let follow = Profiles["followers"] as? Int {
self.followers = follow
// The value here says 788
print(self.followers)

}



}
DispatchQueue.main.async {

}
}

} catch let error as NSError {
print(error)
}

}

}).resume()


print("Followers is")
// The value here says 0 every time
print(followers)
// I have even tried
print(self.followers)

}


As you can see the followers variable is set to 0 When I do my HttpPost i can see that the Variable is set to 788 when I have print(self.followers) however outside of that for Loop when I access the variable it's value goes back to 0 . How can I correct that mistake as I am learning Swift by building an app.

Answer

You misunderstand how async code works.

When you set up an NSSession data task, the call to task.resume() returns immediately, before the network request has been sent out.

You should put the code that handles the response INSIDE the completion handler. Even though your The value here says 0 print statement happens after you call resume on the network task, the data has not bee retrieved yet.

Imagine you are cooking dinner and you send your kid out to get a bag of flour. You say "Kid, go get me some flour. Press the buzzer on the apartment door when you're back and I'll buzz you in."

You then turn back to cooking the other parts of dinner, but you don't expect that the instant you tell your kid to go get flour, you'll look down on the counter and the flour will be there. You know that you have to wait until the buzzer buzzes, and then your kid will be back with the flour.

Submitting a network task is like that. The call to task.resume() is your request for flour. You submit the request, but you go on with what you are doing before the request has finished processing. The completion handler running is the buzzer that lets you know your kid is back with the flour.