JSON Decoding Playground for Swift

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi my name is stuart lynch and in this video i'd like to share with you a multi-page swift playground that i created that i use to test decoding of json you'll come across json objects all the time and i often use it to mock data or to provide sample data in my apps i can store that json file in the app bundle or in the applications documents directory or i can use a url to fetch some sample json this playground shows you how you can test decoding of json from all three of those sources now before i get started let me request that if you enjoy this video please leave a comment below and give it a thumbs up and subscribe to my channel but make sure you ring the bell to be notified of new videos and if you want to support my work you can buy me a coffee if this is something you want to learn how to use then keep watching you can download the playground from the link in the description below if you open the playground and it doesn't look like this i can show you how to fix it perhaps it looks like this if that's the case then you need to make sure that the playground is showing rendered markup so choose editor show rendered markup and you can see here that i've gone to the xcode preferences and set a keyboard shortcut for this since i use it all the time there won't be one by default you'll also want to have access to the sidebar so make sure you toggle it so that it is displayed the keyboard shortcut for that is command 0. the playground itself has four pages this introduction and three more pages to cover the different sources for your json file so let's get started first with decoding from bundle when you drag files directly into the project navigator of your app the files become part of the application bundle each playground page has its own equivalent of that location and that's the resources folder the resources folder for the entire playground also serves as a shared app bundle for all pages but i want to work with them independently when you download the starter project you would have found a file called users.json let's drag this file into the resources folder of that first playground page and let's take a look at it this is an array of json objects the object has eight properties two of which are json objects themselves i have an entire series on json and the codable protocol so if you're not familiar with json you should check this out i'll leave a link in the notes below what we're going to have to do is to create a model for the json before that however you'll need to know how this json was created i have a video on that topic too that might help you out so i'll leave a link in the notes below for that in the next section of this video i'll show you another trick anyway once you have that json file you need as i mentioned to create the model and you can do this manually or you can use one of many tools one that is used a lot by developers is the quick type dot io website you can just paste it in and it'll create the model struct for you i prefer however to use ducky model editor an application available for mac os and i've got a video on this product as well well enough of the self-promotion let's get started i've copied the json from the file to the clipboard and if i open ducky and create a new document i can paste it into the top section immediately the structure is created in the bottom pane on the right i'll give my model a name and i'm going to call mine user you can see that my user model has been created with nested structs if you don't like nested structs you can change that to one of the other two options often i'll use flat but for this example i'm going to stick with the nested model so let me copy that model if i return now to the playground page in the section where it indicates that i start by entering my model i'll just paste it in and i can remove the imported foundation as i've already done that the next line shows me how to decode the json it just so happens that i've used this same model for my example but hopefully you'll catch on i create a variable that will represent my decoded object or objects since i have an array i'm going to say let users to represent that array of user objects i can then use a function that i've created that is an extension of bundle and you can see that in the sources folder for the entire playground this will accept any object that is a decodable object so our array of users does conform along with the name of the file that is in the bundle along with the date decoding strategy and key decoding strategy that you can enter if you don't want to use the default provided i'll not be using any of those date decoding or key decoding strategies other than the defaults so i'll just be leaving them out but you can find out all about them in the series that i referenced earlier if along the decoding path of the function an error occurs it raises a fatal error so you'll be able to see the error in the console of the playground so you'll see what will be required to fix your model or json once successful it returns the decoded data which in our case will be that array of users so let's complete this line by calling the function on this bundle extension we decode that array of self the type from the file name users.json now that we have this array of users we can work with it for example we can print the number of items that are in the array so print user stock count when i run the playground i don't get any errors and 10 is printed that's the number of users in the array well we can loop through the users to see what we can get for example let me just take a look at this model once more we can print out the user's name how about the users address city within the loop let's also print out some separator dashes just so we can see clearly how they're separated let's test it perfect that's all there is to it you upload a json file create your model retrieve the decoded objects into a variable and test so let's move on then to decoding from a url perhaps the most common thing you'll be doing is retrieving your data from an api i'm going to be using the json placeholder api for this example one of the endpoints here is the user's endpoint if i click on this link i see that it generates the json that will be retrieved by your app does this look familiar yes it's the same json that i used in the first example so we can speed through this page the model we'll use here will be the same one that we used in our first example so let's go back there and then we'll copy the model from there and paste it into our new playground pages model section in the next step we're going to create an instance of an api service class that requires a string representation of the url from where we're getting the json and that was our json placeholder site the api service class like the bundle extension is in the sources folder for the entire playground and it's marked as being public so it is accessible from the playgrounds module page the initializer here requires a url string once it's been initialized we can run a get json function and it has two flavors both are asynchronous but have different signatures first is old school that has those date decoding and key decoding parameters that have defaults so we can ignore them if we want to use the defaults and a completion handler that provides us with that decodable object just as the bundle decoder did the second is the async and await version that i've marked as being available for ios 14 and higher now i know that with xcode 13.2 the new swift's concurrency has been made backward compatible to ios 13.2 but there are some caveats that i don't want to get into with this playground so if you're running the playground and want to test as you would for a project running ios 13 i'd recommend that you use the first function otherwise i would use this new throwing asynchronous function that returns the generic object in both cases though if the url is invalid or there is a problem decoding it throws an error so let's show you how to use both back in the playground first we'll follow the instructions by creating an instance of the api service passing in the string for the url so you'll make sure you get that from the api documentation now that we have the api service instance we can call one of those two functions let's first call that more recent one the async method and for this we'll need to set up an asynchronous unit of work that's called a task then in the task we can let our users be equal to the asynchronous version of the api service get json function we're getting an error that it's ambiguous because we need to specify what we expect to get back for this and that's an array of user now the error is saying it can call throw but it's not marked with try so we'll have to do that then it says the expression is async but not marked with the weight so we'll add that as well well now that we have our users we can do the same thing that we did in our first example by getting the count of users and looping through them so we can just reuse that code from the first example when i run this i get the same result so let's take a look at the completion handler version already have our api service instance so we'll call this function using our completion handler version api service dot get json and that provides us with a decodable object that we can use in our completion handler function and we'll call that users we run into the same issue as before where we need to be clear what we expect users to be which is of course our array of user and we have to make sure that we surround this with brackets now that we have users we can reuse the same code as above i'll run this once more and i see we get that array printed twice now before i move on to the last example however i want to show you how to generate a file from retrieve json i have another extension in the sources folder for file manager and we'll be using that more in the next example but it's useful here for one particular function and it's a static function that's called encode and save where you can pass in objects to be encoded and it'll also ask for the name of the document that you want to have saved it then encodes the objects as json data converts it to a string and saves it to the applications documents directory and then prints out that location so back in our playground in one of our functions once we have our array of users let's save it as a json file so we can do that by calling the file manager encode and save passing in our users as the objects giving it the file name users.json when i run this if we scroll back up we'll see that the location is printed to the console it's the location for the document directory for this page well that's great now that it's in the documents folder i can use it for the next page and to locate the documents folder you can go back to the finder and then choose from the go menu go to folder and then just paste in that url and hit go so there it is we can see it's here on the last page now this will be almost identical to the decode from bundle as we are using the same json but it's just in a different location so this is using the same model as before so we'll pick that up from the bundle section and paste it into the model section here of our final playground page so let's check that file manager extension and we'll take a look at the static decode function and see that it works pretty much identically to the decode function for bundle it first however checks to see if the file exists and i generate the url and try to decode it returning the decoded objects successful otherwise printing out any error that i may have encountered so back in our playground we decode the array of users from the documents directory using the file manager static function for our users is equal to file manager decode the array of users the type self from users.json once we have the users we can test and the test will be the same as before so we'll just paste that in let's run it tells me i'm getting an error it's failed to locate the file yet we saw it there didn't we in the last one well the reason is that every page in a multi-page playground has its own document directory we can see that i had up here at the top a print that prints the path so let's copy that path and we'll go to the finder and i'll create a new window so that we can find the documents folder by going to that folder using the go menu go to folder option once more when i go there indeed i see it's empty yet i still see it there in the documents folder from my previous page so let's just move it from there into this one let's run it once more great it works now well i hope you find this playground useful and will be able to make use of it when testing decoding of json in your projects having a playground to do your testing can come in very handy indeed if you agree please like this video and leave a comment then go to the completed project on github and star the repo so that others will be able to find it and use it too thanks for watching [Music]
Info
Channel: Stewart Lynch
Views: 683
Rating: undefined out of 5
Keywords:
Id: -UUyo3bOlys
Channel Id: undefined
Length: 17min 55sec (1075 seconds)
Published: Sun Dec 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.