-
Notifications
You must be signed in to change notification settings - Fork 2
Tutorial
Let's look at a typical NSPredicate
query expression, created at runtime with the builtin parser. This expression queries for all objects whose age
is between 21 and 42:
let predicate = NSPredicate(format:"age > 21 AND age < 42")
The equivalent in PredicatePal is just:
let age = Key<Int>("age") // #1
let predicate = *(age > 21 && age < 42) // #2
In line #1, we define the type of the Key
age
to be Int
. This helps the compiler type-check your expression and also allows the right operator overload to apply here.
In line #2, we compose the Key
and some constants into an expression age > 21 && age < 42
. Then we apply the build operator *
to turn this into an NSPredicate
.
Often, such expressions can be made terser, since Swift will deduce the types when they are unambiguous. So the expression could also be written:
let predicate = *(Key("age") > 21 && Key("age") < 42)
Expressions are made from terms, composed together with various operator and functions.
Terms are Swift generic structs created via their initializers. Their generic parameter defines their expression type, so e.g. Key<Int>("age")
defines the key path age
to have an Int
type.
While you can create constants manually with Const
initializer, PredicatePal will automatically promote regular Swift variables and constants to Const
in a binary expression e.g. in age > 21
, the RHS is a Swift constant that is automatically promoted to Const
.
More complicated expressions are also Swift generic structs, but with internal initializers. You can only create these by using their matching operators or functions e.g. age > 21
actually creates a ComparisonPredicate
generic struct as an implementation detail.
See Syntax for an exhaustive list of our terms and expressions.
The build operator is the prefix operator *. This takes an expression and builds its corresponding NSExpression
or NSPredicate
as appropriate.
You can mix and match PredicatePal expressions with regular Swift expressions, allowing for a great deal of flexibility. For example:
var beauty: Int
let age = Key<Int>("age")
let predicate = *(age - 10 < beauty && age + 10 > beauty)
Here beauty
is a regular Swift variable that is incorporated inline into the expression. Its current value is promoted to a Const
in the final expression.
The equivalent in the NSPredicate
query language would be:
var beauty: Int
let predicate = NSPredicate(format:"age - 10 < %d AND age - 10 > %d", beauty, beauty)