NSPredicate for Swift

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
ns predicate is a foundation class that specifies how data should be fetched or filtered its query language predicates represent logical conditions which you can use to filter collections of objects you use it to find cloud kit object references or when filtering core data fetch requests i use realm as my data store and use ns predicate when filtering realm collections you'll encounter ns predicate many times during your development career so in this video i'd like to introduce you to nsprediket and give you a foundation that you can apply everywhere we'll use a variety of comparison operators and arguments with and without variable substitution we use predicate options compound predicates and the predicate evaluate method if this is something you want to learn then keep watching we'll be using an xcode playground that i've created as a starter project and you can download it from the link in the description below the playground has this introduction along with four pages that we'll work through each page has one or more sections with some comments that will lead us through a series of exercises the code sections are simply a closure that will allow us to repeat variables or functions on the same page with the same name without worrying about naming conflicts i use a technique i learned from ray wenderlich to enable this and to use this function that you can find in the global sources folder so that it is available to all pages all it does is separate the code in a closure and when we print or dump any information to the console we'll be separated by this comment you will see if you've watched other recent videos of mine that use a playground that this will be familiar to you the other file in the global sources folder is one where i've created two public classes one for sport with three properties and the other for athlete which also has three properties one is which is a sport object we're going to be using ns predicate to filter an array of these objects and i've created a statica property of athletes called all that will return an array of 10 athletes this just happens to be the top 10 athlete earners of 2020 based on salary and endorsements the salary property in the sports object is in millions of dollars so let's get started the first thing i want to do is a quick review of using the filter method on arrays and i've covered this in some detail in one of my earlier videos when i covered higher order functions in swift i'll leave a link in the description below let's do a simple filter to find all athletes with the first name of carson i'll assign this to the constant first name is carson and call the filter method on the static all array of the athlete class i'm going to put the filter method on the second line for clarity we'll use the trailing closure syntax for the filter method with dollar zero dot first name equals equals carson if we want to see what the result is i could type print first name is carson but i see that's not very helpful i don't actually see the result so instead i'll use dump we see clearly the result on our console great in the second example we want to find all athletes with the first name containing the letter c and for this we can use the contains method when we dump these results we get one result but where is carson and the problem is that c is lower cased and that matches christiano but not carson which has a capital c the way i get around this here is to chain a lowercase method on the filter before contains this gives us our desired result the next example is asking us to find all athletes with a salary exceeding 100 million now salary is a property of the sport object so we can drill down on that using sport.salary and return all that are greater than 100 and there are three of them if we want to filter out athletes making between 70 and 100 million we have to use a compound and or double ampersand filter like this and there are three of these athletes as well now this is a brief set of examples just to set the tone for this video if you want more information on filter for arrays please watch that video i referenced earlier the main purpose of this video is ns predicate to form our filter criteria so let's see if we can replace the same examples as these but use ns predicate well the problem is we can't use ns predicate on swift arrays ns predicate works only with ns arrays so this means we'll have to do two things to our classes first we'll need to conform them to ns object and make its members visible to the objective-c runtime conforming to ns object is easy this requires no other modifiers to our array other than conforming to the ns object to expose the objective-c runtime we'll need to decorate the class with at objective-c members i said however that ns predicate works only on an sra so returning to our class definition i'm going to create one more public static property that is a computed property that simply converts our array to an nsra so now instead of referencing athlete.all in our examples we'll use athletes.all nsra instead just to check though if we go back to our first playground page we see that the filter still works as we are still working in this case with array.all so let's get started now with ns predicate we're going to use the same format that we did in the first playground and i'll start by defining our constant on the first line referencing this time our all ns array and then i'll call the filtered function for ns arrays on the second line this has a parameter using which is an ns predicate and we will use the format option now for the time being we're going to ignore the optional args argument and just formulate our criteria as hard-coded strings to match criteria it's easy we want to compare the first name property for carson and we can use either a single or a double equal sign here and we'll need to surround carson with single quotes as it's a string we can dump the results and see we get the same thing that we had in our previous example it turns out that our second example is going to be even easier than we had before we can still use the contains keyword and as we see on the first run we just get that single entry for christiano and not carson but with ns predicate we can add a predicate option of c surrounded by brackets to ignore case now don't confuse this c with this one they're not related ignoring case on a predicate always uses bracket c this time we get both carson and cristiano as expected for high earners our query is similar to the array filter we will filter using the ns predicate with the format sport.salary is greater than 100. same results as before good now for our mid-range earners ns predicate has a predicate reserved word called between all capital letters that allows us to use two arguments as long as we enclose them in braces so filtered using an ns predicate with a format of sport dot salary between 70 comma 100 oops i guess i had better dump the results that's better and this is much easier than the array filter in my opinion so here is a list of all the basic comparison operators in ns predicate now we've already used contains comparison operator and it's used on strings but with ns predicate there are more we've got begins with contains ends with like and matches now matches is an interesting one and i'll leave that for a later video as it uses a regex style comparison and that's beyond the scope of this introduction but let's take a look at begins with and like ends with will be similar to begins with and i'll leave that up to you so to find an athlete whose last name begins with the letter m we can use begins with m and include the c in bracket to ensure case and sensitivity so it'll be filtered using the ns predicate format last name begins with m that's pretty simple and we find lionel messi looking at our data we see that we have some football and some basketball players and we could do a filter based on contains that will find all athletes that play a ball sport but i will use like instead and with like i can use a wild card asterisk or a question mark character where asterisk is 0 or more characters whereas the question mark matches exactly one character so for our filter we can use like with case and sensitivity with an asterisk matching 0 more characters before the string ball i see we get 5 football and basketball players if we want to further restrict this to only ball players beginning with the letter f we could use like by starting with the letter f followed by an asterisk which means zero or more characters and then the ball string like this and we see we get our two footballers so far our ns predicates have been formulated using hard-coded string comparisons this is realistic we will really want to pass in some criteria to an ns predicate that will change depending on what criteria i'm filtering for the inclination might be to use string interpolation since we're using swift for example let's copy all of our code from this previous section and paste it into our next section in our first example let's create a variable for our name like this and use name to replace the hard-coded carson this works but you'll never see this remember in the previous section we ignored the argument section well it turns out that ns predicate uses replacement arguments that will begin with the percent to represent variables that can be substituted we can use percent a to represent a string and percent d to represent a whole numerical value so we can rewrite this example using an argument like this and we see we get our expected result for the next example we'll create a variable called letter and we'll assign it the string c and adjust our predicate like this oops i guess i better uncomment that previous dump good now next because our value is a whole number we need to use percent d instead so let's create a high min constant of 100 and using percent d and heimin as our argument now if there are two arguments we can use the same percent substitution variable for both but the arguments are separated by a comma and they are substituted in order so in this example we'll create a lower limit and a higher limit constant with values and we'll substitute them in using percent d as our substitution argument variable and making sure that we have lower limit followed by higher limit as the replacement variables now pause the video now and see if you can fix the remaining three in this section remember to create a constant or a variable first and then use either percent d or percent a as your substitution variable and check your results when you start the video again i'm going to do some fast typing here to do it myself now there's one more thing that i want to do before i leave this playground we've already seen that bracket c comparison predicate option will ignore cases when filtering and this is very handy there's one more though if we take a look at the data once more you'll notice that neymar actually has a last name and it's da silva santos junior and you'll notice that junior has a u with a diacritic this accent above the u and this is foreign to us english speakers but not at all to most other languages now the innocent thing is that junior with the accent and junior in english with no accent mean the same thing if we had some other athletes with the junior suffix and we wanted to find out who they were how would we do that well let me start by defining a constant name and we'll use the english spelling then i'll filter using contains and percent a as the argument and substitution with our name as the variable using the bracket c we can ignore any cases but running this right now i see i don't get name r well there is one more option that i can use and that is d within the brackets and what that does is it ignores any diacritic you can use just c or d alone or both as i have here and running this it works in this section we want to take a look at two different ways of building compound predicates this means satisfying more than one comparison condition and ns predicate has these operators available to us in the first example we have two different pieces of criteria the first the sport must be soccer and in the second they have to have more than 100 million dollars per year in endorsements and salary so let's use the argument substitution which means we'll need two variables or constants that we can use for substitution one for sport which we'll say is soccer and the other for high min which is 100 and this time we're going to enter 100.0 for a change we'll build our predicate using percent a to compare the sport name with case and sensitivity and we'll use percent d for the comparison to sport.salary and in between we can use either the word and or the double ampersand when i run this i see that we get three results but wait this salary is not over 100 million and the reason is that we used percent d which should represent a integer or whole value well 100.0 is either a double or a float and we can solve this by changing our argument to percent f instead of percent d this once again we're good always check your results now for the second example i'll create three variables one for position one which will be a forward and one for position two which will be a guard and one for sport which will be soccer and this time we need an or condition which we can use either or or two vertical lines and we have to make sure that we surround this condition with parentheses to make sure that it's evaluated as a unit now since our positions in our array are small forward or point guard we'll need to use contains on both to look only for our variable strings and make sure that we are case insensitive now for our and condition we want to exclude the sport name being soccer and we can do this in two ways let's use not equal to and make sure that we ignore case and compare sport name not equal to our variable and make sure we add our argument variables as we see we have three such individuals now the alternative to this would be to remove the knot from in front of the equal sign and instead place the word knot in front of the predicate either way works now instead of building my compound queries entirely within the predicate format we can build individual ns predicates and join them together using what is a compound predicate so let's take a look at this example we need three different variables here the ball string the upper limit and the lower limit that we want to use so let's create these three variables this is very similar to what we did in the previous example now instead of building one big predicate as we did in that last example let's build two individual predicates we'll let mid-range earners predicate be an ns predicate with a format where the dot salary is between our two substitution variables and then we'll let ball game athlete's predicate be an ns predicate where the format uses the case insensitive like to compare sport.name to our ball gamer substitution now we can create a new constant call mid-range ball game players that will start with the athletes.all nsra as we have in the past using the filtered method this time we'll use a ns compound predicate instead and see that we have three different choices and in this case we'll want to use the and option so we can use and predicate with sub predicates and the array we'll just insert our two sub-predicates that we've just defined and if we run this we see that we get stephen curry and the bronze genes matching that criteria i want to finish off this introductory tutorial by showing you one more thing and that is the ns predicate evaluate method or function let's start as always now by creating our variable higher min and set it at 100. i'll create a standalone predicate that will compare sport.salary to the substitution variable using percent d now what we can do is use the filter method not filtered with an ed which a boolean value indicating whether the specified object matches the conditions specified by the predicate this is just like the irregular array filter so i will use athlete as the individual object that's getting checked and then we can use the predicates evaluate method on this object as it steps through and if you've watched any of my videos on higher order functions for arrays like map and filter you'll see that i often remove this first part and use the dollar zero substitution instead like this now for this final example i'm moving away from our athlete class and i'm going to look at this simple array of strings called rainbow and it just contains strings representing the colors of the rainbow if i want to find all colors that do not contain the letter e i can use a case insensitive contains comparison operator and if i want to evaluate our ns array it's a simple one with no properties we can use self all capitals to represent the array as we're comparing our criteria to the entire object and then to exclude the contains we can preface it with not now we can let no colors equal rainbow dot filter no predicate evaluate with dollar zero simple well that's it we've covered the basics and perhaps a little more on using ns predicates what i didn't cover was the match comparison operator that uses regex and an alternative keypath argument substitution so leave a comment below if you're interested in the video on those parts of ns predicate [Music] i have lots of other videos 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: 1,560
Rating: undefined out of 5
Keywords: NSPredicate, Xcode, Swift, Filter, NSArray, NSObject
Id: 9CoUUCL03tA
Channel Id: undefined
Length: 27min 5sec (1625 seconds)
Published: Sun Jan 03 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.