15. Decoding Generic JSON Response | Swift 5, XCode 12

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hey guys welcome back to my channel my name is emmanuel for those of you who don't know and uh today we're going to be working on the last major component of our network service in the last video we were able to make a request and then get a response a json response so in this video what we want to do is whenever we get the response we want to directly decode that data or yeah decode that into a swift object that our system is gonna be familiar with all right so uh let's let's jump right in and if you haven't subscribed take a second click on the subscribe button and like the video because i'm sure you're going to love this all right so the first thing we want to do is we want to create a new struct which we're going to call api response now this is going to be the structure of data that we're going to be getting from the back end now if you remember from the sample of the request we got in the last video we saw a status we saw the um uh the data and the message i think so we're going to be creating a structure that's going to be called api response all right and because we want this to decode just go ahead and make this conform to the codable and again if you wanted to if you were thinking of having this to also encode then you could also have or just simply use codable because this is the combination of both the decodable and the encodable all right so i'm just going to be using the decoder because that's all we're going to be doing here now the first thing we know that our data our response has is the status now the status is of type int so we have status codes like 100 200 200 like success 201 400 500 you know all of these numbers they are integers right there's no 50.2 or something so uh we have this status the next thing we have is the message so this is when uh and this is actually of type string and you can go ahead and make this optional just in case there is no message at the back and i actually like to do this just to be a hundred percent sure that it's not going to crash because the data type is or the data wasn't passed into the response all right so uh this message is going to be used to tell us um let's say we we create something then the success message is going to be here so that we can display the message from the backend rather than having to type our own success message within the app now the next thing we're going to have is error or let's do data first so data is very interesting because we're going to be having different types of data right it could be a string it could be an integer it could be a custom type of maybe order in our example or a dish you know so um this we're going to be using a t to represent our generics again you can't escape this so um you're just going to specify the t and of course t is going to be optional because we don't know whether or not it's going to be passed in and you remember whenever we we do this type of thing system doesn't know what t means so what we need to do here is specify what t is so i'm going to say t is of type decodable or includable whatever you want to say so this just simply means that t is going to be dynamic as long as we can decode json into that particular structure all right now the last thing we're going to have is error which is going to be an optional string so in case there's an error from the back end then this value is going to be populated automatically now this is our general api response structure and the beauty about this is uh you can the network service in general is you can actually just copy all of these code that i'm writing over here and you can use it in multiple projects everything remains the same now the only thing you you're probably gonna do is to improve on the um maybe the performance or uh maybe make it a little bit more robust so let's say for example you want to have like timeouts right so you don't want your your request to just continuously roll one it's time out of the particular time so you can of course set that in your um network service where you have where we're generating our url request right so there are many other things that you can do but overall this is a pretty solid architecture or pretty solid um design that you can use in multiple projects right so now we have our api response what we're going to do is we're going to head over to our network service and the next thing here that want to do is we want to implement the next function that is going to help us extract or rather decode the data into our custom type okay so i'm going to do that right under our request function all right so what we're going to be doing over here we're going to create a private function do i know how to split private so we're going to be creating a private function which i'm going to call handle response all right now um this function is going to take two parameters just two the first one is going to be the results that we generated in our last video so the result is of type let's just because i'm extremely lazy i'm gonna paste that right there and then the second parameter is going to be our completion which is of course where you're at my friend i'm gonna copy this like that and we're gonna paste that over here okay well this is the next line so the first one is the results so this results has whether or not it is it tells us whether or not there is an error or there is actual data so and then the completion is us trying to return the decoded data into the exact structure that was initially specified all right so um right here we're going to need to specify what t is and we know that t is anything that is decodable all right perfect so now the first thing we want to do is want to check if there is a result so we're going to say um guard results let's remember equals results else so um at this point there ain't no results so what we're gonna do is we're gonna call our completion and our completion is gonna tell our ui that's look i don't know what happened so we're going to say app error dots unknown error all right now if there is a result what we want to do is want to use a switch and say switch results okay and now what this is going to do is it's going to ask us to implement two things the success and the failure now for the success at this point we have our data and for the failure at this point we have our error now in order to quickly implement the error part we're going to be doing the same thing so we're going to say completion dot failure and we're going to pass in the error over there now for the part of the success so at this point we know that we have data i remember the data may have error or the actual data that we want but how do we know we have to do the actual decoding so what i'm going to do here is i'm going to say at this point i'm going to say let's decoder be equal to json decoder all right now i'm going to do a guard and say let our response so this is going to be our decoded response is going to be equal to try and we're going to say uh decoder dot decode what did i write dot decode from and the type we're going to do here or we're going to use here is we're going to just say t because t is the uh not t actually but we're trying to decode using our api response structure so we have to specify api response and then inside of our api response we have a generic type right so the t so we're going to specify t which is whatever is going to be our decodable type in this case all right so i'm just going to put that over here and then we're going to need to specify self now let me just quickly explain this again now you know in our whenever we receive a response we have the the status we have the success let's quickly just go there so we have all of these things but within all of these so all of these have like defined types right but this one does not so the data can be different right it can be a string it can be a um dish an order whatever so um since this is different we we're specifying that there's a generic type within the structure so that's what we're doing over here we're saying that we want to decode to this but then there's something want to pass in an extra type that you're going to use to decode whatever is within that particular um structure all right i hope it makes sense but we're going to see it work all right so now for the data so you can see over here that we have data right here you can just see type so we pass in data just like that and since you're using a guard you're going to have an else so at this point if we get an error it means that the decoding was not successful so i'm going to just do a failure and say um error as app error dot decode eretically so um yeah so this is going to return error decoding as the error message so if we didn't get that it means that the response was successful so now did it decode with an error or did it decode with actual data that's what we're going to check now so we're going to say if let's error equals response.error then at this point it means that there was actually um an error in our um response so what we're going to do is we're going to say completion again dots failure nope what am i thinking and for this part we're going to specify an app error so it's expecting an error object so i'm going to say app error and this is going to be a server error and i think i should have used the better name server is like 500 but i'm just going to pass in the error which is of type string as you see over here perfect let's get rid of this now um now that it is done we can actually just go ahead and add a return just so it doesn't spill or we can use an else if if you will all right so uh but what i'm going to do over here is now i want to check so uh if there's an error it goes but i want to check if there's actually data there so uh what i'm going to do is i'm going to say if let data equals response dots data actually let me use something quite different let's say decoded data right and um yep so if there is a decoded data then we want to do something otherwise then maybe we want to say that um there's no data or known or whatever so what i'm going to do is i'm going to say completion dot uh why don't we say question dot so failure and here i'm going to say app error dot and let's say for example uh maybe you can say unknown or you can say error decoding right whatever you choose so um yeah if there's no actual data or we could actually even create a new one and say there's no data you know so uh when we're done um now we have access to our decoded data and you can see that as of type t so whatever the user is expecting when we're calling the function it's going to decode to that particular type so what we want to do is we want to say completion and this time we're going to say success finally success and it's expecting a decodable so what do we do just pass in decoded data so this is our um handle response function and i guess this is doing a pretty good job so what i'm going to do is i'm going to you know have to connect that over here so to do that we're going to call self dot handle response and handler response expects the results we have that lucky and for the completion is going to be the exact same type as was passed in here so i'm gonna pass in completion and let's see if everything is okay any complaints no complaints awesome so that is pretty good now what i'm going to do is i'm going to run this program again and this time i expect that it fails let's see what we're missing um escape enclosure yeah so we're going to need to make this where's the completion i'm gonna make this escape so just add ads and escaping over here let's copy that we're gonna need to do it somewhere else let's see bill please um is that okay all right so anyhow um let's go ahead and run this so i'm going to add a a completion over here in this function just so that we can check the data from another place so at the point where this particular function is called so what i'm going to do here is i'm going to specify a type that i want to that i want to get so i'm going to say i want to get a how do i say this so i'm going to say add escaping over here and what am i doing completion and this i want to get a results and for the results i want to get a string and an error if there is an error all right yep okay now rather than having like an empty brace over here i want to directly call out completion so this is simply saying um make the request call the make the request and um i want my response to be decoded into string all right and if you actually look at this you see that we really didn't need to specify the type over here right so i think what i'm going to do is i'm going to remove the type from over here because i didn't see us using the typo here so uh we used the direct um we use the direct data that was passed in our completion so our completion type here is string so it's going to decode directly to the string so if we wanted to decode directly to an integer then we'll be calling the function and pass an interior integer over here so we don't exactly need to specify an extra parameter for the type all right i hope that makes sense so now let's head back into our home controller and what we're going to do here so this is going to be quite different so my first request now has a completion all right that's executed when the response is retrieved and decoded so here i'm going to say results and in order to get the data i'm just going to add a switch i was switching the results so case first is going to be success and you can see automatically it already specified the type of data that we're going to be receiving when we do the um what's it called when we get the response right and the second parameter we're going to have here is the failures and again error so here i'll just say let error and we're going to print the error is this is going to give us error dot localized description awesome and for this one we're going to say data and print the decoded data is data now if we run this program can you guess what the output is going to be okay let's run it and see [Music] okay so as you can see over here uh we got the response and we got the pretty good response but right here it said response could not be decoded and the thing is we're trying to decode this data as a string so if you look at the function over here we specify that this is going to be of type string when in fact when we look at the data this is the data object over here this is in fact not a string right so um this returned the error so if we wanted to change this we're going to need to do is to pass in the actual type that matches this particular data structure so what i'm going to do is i'm going to check for the existing one that we have and if we look over here we have a dish right so we have a disk format that looks pretty good so what i'm going to do very quickly just for us to test that it works is i'm going to make this decodable all right so making a decodable means that we can directly decode from our json data into this particular swift structure all right so now that we have this remember this doesn't match the type but i'm going to make a change to our temp request and i'm going to be pointing to a different route that returns a list of dishes all right and this is simply um slash dishes slash the category number so i'm going to return one i think this works remember this is just like temporary so what i'm going to do is i'm going to run this one more time just to be sure that it returns an actual data and don't worry about how i'm getting this thing maybe maybe maybe sometime i may make a video uh just showing what the back-end does but um this is like you connecting to a back-end so the back-end is going to you're gonna gonna be giving a particular route to call and then it gives you a response so uh this doesn't work he says the response is this uh error cannot be decoded so i guess i passed in a bad route so i think it's actually dishes okay so i was able to confirm that the category is actually cat one or cat two i think so um yeah i'm going to make the request one more time and i expect this to fail but i just want to see that i get some actual data in our array okay so um let's see see what we get all right perfect so now we see that we get actual data so let's see what this data actually looks like so data is an array of dish so this is a dish object that has id and the name and the description so what i will do then is i'm going to go over because if you look over at the bottom we're going to see that decoding still failed so i'm going to head over to our network service and what i'm going to do in fact here is i'm going to change this to an array of dish so our results should be an array of dish now let's run it one more time and if let's see if we still see this error or it actually decodes fingers crossed let me give you time to cross my fingers so this thing didn't work yeah so it said necro service requires that dish conform to encodable so let's head over to dish and how do we fix that oh okay so because i specify that it has to be encodable so i'm gonna have to say encodable or i change our requests where's the requests and the request here i'll just change this to decodable all right i think that's better since i'm not um encoding it so now let's run it again and hopefully everything should work pretty smoothly now you can cross your fingers and uh if you're finding whatever value and what i'm doing over here then please take a second and hit the subscribe button and if you've enjoyed it then please also hit the thumbs up so that other people can know that the tutorial actually makes sense and all the more reason why you should do it it actually worked awesome so um let's let's come over here now this is our json right this is our json data and if you look over here it says the decoded data is and now things are a little bit different it isn't like our json but instead this is an array of yummy.dish meaning this is our particular data structure and if you see the id is item and everything properly decoded now if you wanted to see it let's say we wanted to get all of the names um easily so what we would do is uh let's go to where we made the call which is our home view controller at this point what i could do is just say um for um dish and data and i'm gonna say print dish dot name all right and i just put a default of an empty string and i'm also going to remove that print statement right here just because it's loading up our so just commented that out so let's run it again and this time we should see a simple list of all the dishes that are returned for this particular category and this is the beauty of the coding so you don't have to manually map objects or values you it just does it for you and you enjoy so the network call er will soon be made it's been made and we can see all of our dishes the name and we can do whatever we want we can populate this now table view in our case you're gonna see how everything is gonna tie together so in the next video we will actually start connecting our back end with our ui and we're gonna be using these awesome network service that we've created and this is simply this is just how easy it's going to be for us from uh wherever we want to make the call we just use our shared instance we do this and um we just populated our ui so in case you don't want to wait for it when i release the next video you can try this on your own and i'll be really impressed if you can get it working without um my help all right so um until then stay blessed and see you guys in the next video
Info
Channel: Emmanuel Okwara
Views: 844
Rating: undefined out of 5
Keywords:
Id: 28zR8IZrVmM
Channel Id: undefined
Length: 24min 51sec (1491 seconds)
Published: Sat May 22 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.