Skip to content

Tutorial

Glen Low edited this page Dec 22, 2015 · 2 revisions

Your first expression

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)

Composing expressions

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.

Build operator

The build operator is the prefix operator *. This takes an expression and builds its corresponding NSExpression or NSPredicate as appropriate.

Mixing and matching

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)
Clone this wiki locally