Field Validation and MVVM in SwiftUI

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
this video is going to cover a number of different topics with the focus on learning how to validate data entry in swift UI throat process we'll learn about the mvvm design pattern and use regular expressions to validate the data this is something you want to learn then keep watching we're going to refactor a fairly straightforward swift UI view that displays a sign-up screen that looks like this the starter project has the current view already completed as you can see there is no validation on the fields at all I can enter anything at any time I also utilize a Z stack that displays a schooling selection list of years from which to pick from to populate this year field this is a technique I use a lot when I want to present from a selection of options rather than using these standard swift UI picker views I'll leave it up to you to explore how I've done this but that's not the point of this tutorial I can also tap the signup button at any time as well even when there are no values in the fields and when the passwords don't match so here's the finished project when the app launches notice that there are now some additional prompts prompting the user of what to enter in the fields also the signup button is disabled and the opacity is less than one as soon as I enter the valid data in the fields the prompts disappear when all of the criteria is met the signup button is active and at full opacity and I can complete the signup process whatever that may be and by the way it supports both light and dark mode so that's what we're going to do in this project we want to take this starter project and refactor it to this current one using NPM which is the perfect design pattern in my opinion for Swift UI you can find a link to the starter project in the notes below mvvm stands for model view viewmodel what we have in content view is the view and we want to create a view model that will be responsible for passing the correct information to the view for display you shouldn't really be responsible for generating what prompts go where or how to display different pieces of information it's really just there to lay out the objects if we look at our content view we see we have four different state variables that when changed update our view we could get ourselves into a massive view situation if we start to add that display logic here as it is the view is quite readable the body is the Z stack and it contains two other stacks the visible one right now is the signup stack and this contains three text fields I have extracted a view here that accepts the sf symbol name and a placeholder string as well as a binding for the text field and a boolean value that will indicate whether or not the field is secure we need the secured option if it's a password field to hide the text as typed welcome back to that momentarily the year of birth is actually a button that when tapped toggles the show year selected variable which disables and the entire signup view and sets the opacity of my picker view to 1 the view is always there but it originally has an opacity of 0 so when show selector is false its hidden from view the picker is just a scrolling list of buttons starting at the current year and going back 100 years note the reversed designation when you tap on one the opacity is set back to zero and Berthier is updated with the selected item and the button label is as a result updated with that value now let's go back to the entry field here's that entry field and you see I simply display a secure field or a text field depending on whether or not his secure has been set to true it is set to false by default the view properties just make it look pretty the view itself is embedded in a V stack so wouldn't it be nice if we can add a prompt field below each field so we can then display our prompt so let's just add text this is a prompt for my view to be displayed here notice that the prompt doesn't always wrap to two lines we can fix that with a fixed size with horizontal being false and vertical being true and let's set the font to dot caption to reduce the size somewhat now of course we want to have that prompt text change depending on whether or not the field is valid so we need to pass text that will be different for each field so let's create a string variable called prompt and replace our string with that variable of course this now breaks our view because our entry field is missing the prompt I have three errors now I could click on each and let Xcode fix each one one at a time or I can use control option command F to fix all errors at once and let me just pass in an empty string for the time being so now it's time to create a view model I want to take all of these content variables out of our view and perform any validation elsewhere so let me cut these out here now and I'm going to create a new file called sign up view model inside that file I'll create a new class called sign up view model and I'm going to paste those four variables in but I'll remove the add state private designations we can now return to content view and create a new variable that will initialize an instance of this class as a state variable so at state private var signup and VM is just equal to sign up view model now since we removed our original state variables we'll need to fix our code by adding in the sign up VM in front of those former state variables you now this one doesn't give an error so make sure you catch it I have to add sign up VM in front of birth year as well and I don't need that self here either so far so good the app is still running nicely but not doing any validation so let's return to our view model and work on that the first thing I'm going to do is start dividing my code into sections view model files can tend to get quite large so using a pragma mark to separate the code can be very useful over time I use X code snippets a lot and you'll see shortly as I often don't remember code syntax I created a video on this a while back so you may wish to check it out for example I use my shortcut SW underscore mark to insert a mark pragma with a placeholder that allows me to define my section in this one I'm just going to call it validation functions now I'm gonna have to write four functions and each one will return true if the data entered matches my criteria and each one is for each of the four inputs let me start with the easiest one first I'll check to see if my password and confirm password fields match so function passwords match and I'll return a bool and what I'll return is just the truthfulness of password equals equals confirmed password notice I don't need the return keyword anymore as it's a single statement now how about checking whether or not my password meets my criteria I don't want to allow simple passwords and this is the perfect solution for regular expressions if you're not familiar with regular expressions don't worry there are a lot of resources out there just search for reg X or reg X depending on how you pronounce it I'm not going to go over the specifics I'm just going to point you to a resource to find regular expressions for validation so let me start with this snippet again that I created that I use all the time it's for validation now for every placeholder named field I'm going to replace that with the field that I want the validate so I'll start with password and for the moon we'll leave the red X placeholder alone now regular expressions are patterns used to match character combinations and strings in this NS predicate that we'll be defining with a regular expression will be used to evaluate our password field and return true if it matches the criteria otherwise it's going to return false in my snippet I have a link to a site that I find extremely useful for validation it's a regular expression library that contains useful regular expressions for example let me search for a password I get eight hundred and three different results and as we read through the descriptions it tells us what our string must be and you can pick whatever criteria that you want but let me choose this one says that passwords must be between 8 and 15 characters and include an uppercase a lowercase and a numeric digit I'm just going to copy this and replace my regex placeholder back in my Xcode with that and I get an error about an invalid escape sequence and that's because there's a backslash in our red X which is the escape character in Swift so all I need to do is insert an additional backslash in front of it to escape it it's kind of like a double negative now what this function does is return true only if our password field evaluates by our regular expression to be true otherwise it will return false so let's do one now for email I will use our validation code snippet again and replace our field placeholder with email switching back to our library site I'll search for email this time again 920 results and item to choose the third one as it looks like it's a good one for me I'll copy this regular expression and paste it back into my placeholder in Xcode and I have to make sure that I escape 9 back slashes this time our final check now is to see if our age field is valid in our case we only want allow people if they are turning 21 this year so we can do a check on the current year and subtract the birth year to see if it's greater than or equal to 21 while the current year can be found by date components and I already have this in our default birth year when the instance of our view model is initiated so let me copy that to designate this year and subtract birth year and check if it's greater than or equal to 21 now that I've got my functions created I can create a single computed variable that I'll call is signup complete that will return false if any one of our tests fail so I can use not on our tests and or on each test now if they all pass it'll be true so var is sign up complete a boolean if not password match or not is password valid or not is email valid or not is valid age return false otherwise it will return true now we're almost ready to put this to work however we need some way for our application to know when changes are made to any of these fields we do this by making our signup viewmodel conform to observable object and then we can publish any field we want to watch so in our case email password and confirm password our fields that change as the user enters text so we'll decorate them with at published now we don't need to do that for birth year as we're changing that one right on the content view as we our year we're turning now to content view I'll need to change sign up VM from an at state variable to an observed object and remove the private designation test this so far if our is sign up complete variable in sign up view is false we want to reduce the opacity of our sign up button so we can use the tertiary operator here for opacity if sign up VM is sign up complete the pass it is one else 0.6 similarly if we want to disable the button we can just say that it is disabled if is sign up complete is not true so let's resume our canvas and indeed it's disabled with a 0.6 capacity we can test it out by entering email addresses and passwords and I'll pick a year that makes me at least twenty-one years old and as soon as I do our button is enabled notice that if I entered an invalid email the button gets disabled so far so good but wouldn't it be nice to be able to provide feedback as to which fields aren't valid well we already have our prompts filled in place but they're currently just empty strings so all we need to do is create or computed string variables that will return a string with descriptive content if the corresponding validation check fails so back in our view model file let's create a pragma section for validation prompt strings our first will be our confirm password check so var confirm password prompt be a string and if passwords match return the empty string else return password fields do not match next the email prompt if is email valid return an empty string else return enter a valid email address similarly VAR password prompt string if is password valid will return an empty string else will turn must be between 8 and 15 characters containing at least one number and one capital letter and finally Bar age prompt if is valid age this time we'll just return the caption we already have year of birth else will return year of birth and then in brackets must be 21 years old so now we can return back to our content view to implement this the prompt for email is sign up VM dot email prompt for password its sign up VM password prompt and for confirmed password you guess it sign up VM confirmed password prompt and in the caption below our button for selecting the age the text is just going to be sign up be m dot age prompt now let's resume and test our campus we see our prompts and as the criteria is met the prompts disappear since they'll be set to an empty string when all are met the signup button is at full opacity and active now this has been a long video but let me just add one more thing once the button is tapped you have a function for registering your users or whatever your form submission will do and what you want to do at this point is probably clear the fields afterwards so that you could start all over again for another entry so back in our view model I'm going to create a function called sign up where we would call our storage functions and perhaps receive a call back it would be prudent to note here that in this tutorial we have covered view and view model but we've not talked at all about the model layer and this is the one nice things about mvvm our model can be any type of model required for example we could be working with core data realm or storing data as JSON and the file structure you could use anything but it's at this point that you'd be interacting with your model by passing the validated data from our view model to the model to create a new instance and then perhaps use storage functions to or the result keeping your code completely separate where it belongs once complete however you can set all the values back to their defaults which are these ones so I'll just copy the assignments from our Declaration and paste them here now back in our content view we can call that function when the button is tapped testing one last time after getting an active signup button we can tap it and then the fields are cleared lots of other video is available and in the queue as well so please check out the rest of my channel you can also visit my website to see the apps that I have available on the App Store and visit my github page to see what I have available as public repositories if you like what you've seen give it a thumbs up and subscribe to my channel and ring the bell to get notified when I post new videos I'm most active on Twitter so please follow me there as well to find out what else I'm up to thanks for watching
Info
Channel: Stewart Lynch
Views: 5,175
Rating: undefined out of 5
Keywords: SwiftUI, MVVM, Regular Expressions, iOS, Xcode
Id: 7oMlz-pMSAI
Channel Id: undefined
Length: 19min 3sec (1143 seconds)
Published: Fri Jun 19 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.