Hey, everyone. Welcome back. So we have data. There are some more things we need to do here with our code, but we do have some data and then we need to show that data inside of our table view. So here we are in a network service and we have a design problem. Here in our view controller, we don't want to be mapping data, parsing things. We don't want to do any of that stuff from here. What we want is we just want to get the to-dos and be able to use them here. But remember, it's not synchronous. It's actually asynchronous. Which means when the request is made, our application is going to continue to just do its thing. It's just going to do its thing and it's going to wait for the data to come back. So what we need to do is we actually need to go ahead and grab the data when it's done and then bring it back over here into the application. We're keeping this super simple, but it's really important to know in any case. It's not good practice to just build out tons of logic in your view controller. Things need to be modulized where they need to go. So how can we make this modular and reusable? Well, I think we can use some closures or some callbacks to do this, specifically onSuccess and onFailure. So that's what I want to work with here. When we have success, I want to be able to pass back the appropriate data. So in our getTodos, I'm going to create a new variable here and say onSuccess or rather a parameter and we're going to make a closure, and we're going to say @escaping because this closure is going to be able to escape. It's going to be asynchronous here. We're going to say Todos and then we're going to return Void. Okay. Build this here and it's saying I failed probably because I forgot to put in a label here. Let's build it again. That's what's yelling at me. It's because here in the todo view controller, we've changed the function. That's fine. Let's go back to my network service here. Okay. So we've got a closure here and if you're not familiar with closures, it can take some time to get used to. But in our particular closure here, this closure, we need it to live beyond just what's being run in here because the closer is actually going to be held at least for awhile inside of our view controller. So it needs to be escaping. It needs to be able to leave outside of this function here. What we're going to do is we're going to pass back Todos when the network request is done. This closure is not returning anything, it's just passing in a parameter. So we don't need any return on there which is why we have the Void. So what I can do is I can go down here, see where it says "items"? Okay. What I can do is I can pass in the Todos back over to our view controller. So instead of printing them, what I'm going to do is I'm going to just simply type in onSuccess and we're going to pass in items. I'm going to build this to make sure there's no errors, and there's not. So I'm just calling the closure and passing in the Todos that we just got from the server. Then what I can do is here in our TodoVC, we'll rewrite this function, or recall it I mean, NetworksService.shared.getTodos. Now, I can just press enter to implement my closure here. So when the network request is done, we're going to get back our list of Todos here and then of course we could print them here as well too or show them in the user interface. So let's just print them for now. Let's say debugPrint, I'm going to say todos, and there's one more really important thing I want to do before I build this. So if we go back to our NetworkService. Here we go. So when this network request is made with the dataTask, it's actually going to spin it up on a background thread for us, which is really nice. But the problem is when it's done, it's still on that background thread. It's not on the user interface thread or the UI thread. So if we don't switch our data back to the main thread, our user interface won't update. But if we were to run a network request on the main thread, what would happen is your whole app would stop working until the data request was done and things wouldn't tap and such. So it's very important that your data always gets thrown or tasks that shouldn't be asynchronous always thrown in an asynchronous task or a background task. That's happening automatically right here for us, which is really nice. So what we need to do is say, "Hey, the data is here. Let's just go ahead and put it back on the main thread." So when is the task actually done with its asynchronous part and its back living in iOS? Well, on line 22, it's going to call this and then what's going to happen is none of this is going to be called under here and it's going to go straight to task.resume. Then when the task is done, then it goes here into the callback or the closure here. So what I want to do is I want to wrap all of these errors and success statements inside of the main thread, the user interface thread so I can show errors to the user as well as update the table with data. I don't want to have to do that from the user interface. I think that user interface in the view controller, it should just work automatically without having to worry about threads and things like that. So let me say DispatchQueue.main.async. All this is going to do is whatever is inside of it is now going to run on the user interface thread. This is really important. If you're looking to get a job in the industry, this is one of the very first things they're going to ask you because it's super important. If you heard things about Grand Central Dispatch, well, Grand Central Dispatch is the threading system built under the hood under iOS, and URLSession uses it under the hood to some degree. So this is some nice convenient utility. But anyway, if anyone ever says to you what do you know about multithreading in iOS, or GDC or Grand Dispatch Central or GCD? I can't remember now, Grand Central Dispatch, the ordering. But basically, it means let's throw your tasks on the background that are asynchronous and then when you need to show them to the user, put them back on the main thread, which was what we're doing right here. You can do a lot more with multithreading on iOS, but this is it at its simplest core. I just cut that and put it all here inside of DispatchQueue.main.async. So what I would expect to happen is when I make the request, it's going to call this task here and when it's done, we're still going to get our success and we're still just printing it, but this time we're actually printing it in the view controller over here, like so. It would still print even if we didn't put it on the main thread here. But what wouldn't work is if we tried updating the table view with the data, it likely wouldn't work. So let's go ahead and run it. The user interface would just stand there not doing anything. So it ran automatically and it's still printing. It's just doing it from the view controller now here in our cool little closure. Awesome. So let's call this video done. We successfully have a get request in here working. Then in the next video, I actually want to tie it up to the user interface. So let's do that and let's move on and forward.