Throw, Try, Try? Try! Catch

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
many developers including myself are confused by the different flavors of the try keyword swift defines three variations of the try keyword try try out the question mark and try with the exclamation mark you use the try keyword when you have a function that throws and what the heck does that mean if you're like me and confused as to what throws means and which flavor of trying to use and why then keep watching this video hopefully I'll be able to shed some light basically try indicates that a method must throw an error you can define your own methods using the throws keyword for example you might create your own validate credentials function that takes in a login ID and a password like this if I try to call this function as I would a normal function by passing in a string for username and password and presented with the error call control but is not marked with try so whenever you call this function we have to use a flavor of try before we do that however let's flesh out our throwing function the cleanest way to do this is to use an error enum like this where we define two cases one for when the username does not meet our requirements and another when the password doesn't so case bad username and case bad password let's comment on our function and recreate it with our username and password checks for example we might want to put in some logic into our function that checks to see if our username is longer than three characters and if it doesn't we can throw the appropriate error if the username dot count is less than four then we'll throw credentials error bad username case for our password we want to ensure that there is at least one decimal digit we can do this by using the range of character from the NS character set decimal digits if the range is nil meaning there are no decimal digits then we can throw the credential error bad password case if our credentials pass these tests we arrive at the end of a function so let's just print out past now that we have our function checking for errors and throwing errors we can try to call it if we use try just like this and pass in some failing criteria like when password doesn't have a decimal digit we now get another error an error was thrown and was not caught caught is the key word here it is related to catch so this means we should use a do catch block so we wrap the try in a block like this within the catch block we can check for and deal with any error we might get we can switch on our error and check for which of the credential errors were thrown if it's a bad username we can print user name is too short if it's a bad password password does not contain a decimal number and our case needs to be exhaustive so we'll just break on default let's test oops forgot to comment out the last example test again and we get our bad password error print statement we'll fix it and run again this time it passes let's reduce the length of the username string and run it fails with the bad username arrow print statement clicking it again and running we get a successful run you do have another option here if you do not want to work with enum errors let's call mind out all of this and go back to where we started but this time use a try question mark when we run this we see that the playground indicates that the function generates a null value so we can do our check to see if the try is equal to nil so let's wrap this in a if equals nil and print failed if it is else will print credentials passed bring this now I get the failed statement because the response is nil if I correct the name and run again I'm good the response isn't nil we get past from the function and therefore the else statement is printed normally in your application you'd likely do something like this I'll comment this out first now let's create a login function that accepts a username and a password as string this time we're going to use a guard statement to check to see if our credentials pass guard statements are the opposite of the if statement will use guard and then try to validate the credentials passing in the username and password from the function and this time check if it's not equal to nil if it is then the else kicks in and we print failed and return directly from our function if we pass the guard task or successful I can carry on with our login let's test with this this fails so the guard check fails as well and we exit our function correcting the password we try again this time the guard statement is successful so it bypasses the else statement and we carry on in this example I'm gonna look at something you are bound to come across if you ever access an API and have to parse JSON using JSON decoder in the decodable protocol I have a whole nine part series on this and I'll leave a link in the notes below what I don't do in the series is talk about how and why we use try here's an example that I use in the series I have a JSON string called person JSON it has two key value pairs name and age when we parse this using JSON decoder it will map to a corresponding person struct with two properties of the same name as the keys we define our decoder and then extract the data from the person JSON string since the decoder will only parse a data object and it's a trivial object to decode we can do person equals decoder decode person itself from person JSON data however this gives us an error call can throw but is not marked with a try I don't see any throwing function so what's up with that if you command click on the decode method of our decoder and jump to the definition you'll see that the decode method does throw that's why we need to use try so let's comment this out and see what our options are I'm going to assume that my JSON data is always consistent and my keys matched my struct properties so I'll use try exclamation mark to decode to a person constant and print out the person's name running it works but what if our Jason was bad let's change one of our key values and run again boom and error and your app would crash it's never wise to use try exclamation mark unless you're 1000% sure you'll never have an error or inconsistent JSON it is always safer to use either a try question mark or a do try catch block let me fix our JSON and move on let's comment this as just like the previous example we'll wrap our try in a do catch block if it's successful will print the person name if not we can print out the Aires localized description running the valid JSON prints out our person name let's invalidate the JSON and run again no crash this time however we get the error message instead that we can deal with all right let's fix our JSON once more and then comment out this code and see how we might use try question mark we'll just let person equals try question mark and then decode we know from before that person will be an optional object and we'll be nil if the decoding fails so using a flat person equals person we can print out the name because it's not nil and the person on the left of the equal sign is no longer optional else we print person does not exist running out now we get the person name because our jason is valid let's invalidate the JSON one last time and run it and we get our error string there's an alternate way to deal with this we can use the nil coalesce err when printing remember that person is optional so it has to be person question mark dot name and if that fails the nil coalescing operator question mark question mark allows us to print out our string let's come on up the first version and run we get the same result let's fix the JSON and run once more now we get the name in this last example we'll look at yet another example from my JSON parsing series when you decode an observable object where one of the properties has a published property wrapper you need to define coding keys and an initializer please watch that series for more information it's not that important for the purpose of our video though we just want to point out that our initializer is using try without a do catch block or a question mark so what's with that let me see if I can explain I'm going to be a good citizen here and wrap each of tries in a do catch block and report a fatal error it fails I'll create a person variable and I'll decode to it using a do try/catch block printing the user's name if successful you it still works good let's invalidate the JSON and run once more you see the initializer is the one that is catching the error and printing it out let's revert now to how it was when we first started by removing the do catch blocks on the initializer I'll fix the json and run and it still works great but let's invalidate the json and run this time the error in the initializer is not caught so it bubbles up to the calling method which is the decoder and it's caught there regardless of where you catch your error you have to catch it normally you will see errors bubbling up to the top and that's why you will most often see a simple try in the initializer I hope you found this video useful if so please give it a thumbs up below and subscribe to my channel if I get enough positive feedback I'll continue to build out similar tutorials for Swift developers who have left the starting gate but still need to add to their toolbox you can check out my youtube channel to see what other videos I've created visit my website to see my iOS app portfolio of apps currently on the App Store and check out my github repository to see what else I'm up to thanks for watching I'm most active on Twitter so follow me there for notifications of other Swift related things that I'm up to
Info
Channel: Stewart Lynch
Views: 1,289
Rating: undefined out of 5
Keywords: Try, Throw, Catch, Swift, Xcode, iOS
Id: gn5bqssL_bg
Channel Id: undefined
Length: 13min 37sec (817 seconds)
Published: Sun Mar 01 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.