Nspredicate Cheat Sheet

Posted : admin On 1/25/2022

UI Testing Cheat Sheet alternatives and similar libraries Based on the 'UI Testing' category. Alternatively, view UI Testing Cheat Sheet alternatives based on common mentions on social networks and blogs. This page contain usage examples of common Core Data actions, check here for NSPredicate usage examples 💬. Get Demo CoreData / NSPredicate Xcode Project. Table of Contents. Fetch all records. Fetch records which match condition. Fetch the first N records sorted by property. Delete all records. Delete records which. NSPredicate Enjoy this cheat sheet at its fullest within Dash, the macOS documentation browser. Format String Summary Attribute name. Object's attributeName value is equal to value passed in @'attributeName %@' Keypath. @ApoorvMote, as of Xcode 9.4, Swift 4, yes: if you use a regular Bool value in the predicate, items with nil attribute values will be found. For example, set an attribute's value to nil (we'll say you called it boolAttribute as shown in this answer). Then, create your predicate: let predicate = NSPredicate(format: 'boolAttribute %@', boolValue).Note: boolValue should equal true or false.

Format string summary

@'attributeName %@'

@'%K %@'

@'%name IN $NAME_LIST'

@'name' IN $NAME_LIST'

[NSPredicate predicateWithFormat: @'title %@', @'minecraft']

Keypath collection queries

@avg

@count

Nspredicate Cheat Sheet

@min

@max

@sum

[NSPredicate predicateWithFormat:@'[email protected] < 200']

Object, array, and set operators

@distinctUnionOfObjects

@unionOfObjects

NSArray *payees = [transactions valueForKeyPath:@'@distinctUnionOfObjects.payee']

@distinctUnionOfArrays

@unionOfArrays

These must be run on an array of arrays. For example if you had:

NSArray *arrayOfTransactions = [[Array of transactions], [Array of transactions]]

NSArray *payees = [arrayOfTransactions valueForKeyPath:@'@distinctUnionOfObjects.payee']

@distinctUnionOfSets

Array operations

array[index]

array[FIRST]

array[LAST]

array[SIZE]

Let’s say we have a person with many dogs. index should be replaced with a number which will return the dog that you want to check against. Here we’re checking if the first dog’s age is 5.

[NSPredicate predicateWithFormat:@'dogs[0].age = 5']

Here we’re checking if a person has 3 dogs

[NSPredicate predicateWithFormat:@'dogs[SIZE] = 3']

Basic comparisons

=,

>=,=>

<=,=<

>

<

!=,<>

IN

BETWEEN

[NSPredicate predicateWithFormat: @'expenses BETWEEN {200, 400}']

Basic compound predicates

AND,&&

OR,

Nspredicate cheat sheet printable

NOT,!

[NSPredicate predicateWithFormat: @'age 40 AND price > 67']

String comparison operators

BEGINSWITH

CONTAINS

ENDSWITH

LIKE

MATCHES

[NSPredicate predicateWithFormat: @'name BEGINSWITH 'm']

Aggregate operators

ANY,SOME

ALL

NONE

[NSPredicate predicateWithFormat: @'ALL expenses > 1000']

Subqueries

Iterates through the collection to return qualifying queries

Collection - array or set of objects

variableName - variable that represents an iterated object

predicateFormat - predicate that runs using the variableName

[NSPredicate predicateWithFormat: @'SUBQUERY(tasks, $task,$task.completionDate != nil AND $task.user = 'Alex')[email protected] > 0']

Assume this was run on an array of projects. It will return projects with tasks that were not completed by user Alex

Common mistakes

Using [NSString stringWithFormat:] to build predicates is prone to have non-escaped diacritics or artifacts like an apostrophe. Use [NSPredicate predicateWithFormat:] instead.

Using OROROR instead of IN, results in repeatable code and can be less efficient

When using REGEX and Matches, make sure they are the last part of your predicate statement so it does less work. This way objects will be filtered before doing more heavy look ups.

Using SELF

When using a predicate on an array, SELF refers to each object in the array. Here’s an example: Imagine you are a landlord figuring out which apartments have to pay their water bill. If you have a list of all the city wide apartments that still need to pay called addressesThatOweWaterBill, we can check that against our owned apartments, myApartmentAddresses.

NSPredicate *billingPredicate = [NSPredicate predicateWithFormat: @'SELF IN %@', addressesThatOweWaterBill]

NSArray *myApartmentsThatOweWaterBill = [myApartmentAddresses filteredArrayUsingPredicate:billingPredicate]

LIKE wildcard match with * and ?

* matches 0 or more characters. For example: Let’s say we have an array of names we want to filter

@[@'Sarah', @'Silva', @'silva', @'Silvy', @'Silvia', @'Si*']

predicateWithFormat: @'SELF %@', @'Sarah'

Will return “Sarah”

predicateWithFormat: @'SELF LIKE[c] %@', 'Si*'

Will return “Silva”, “silva”, “Silvy”, “Silvia”, “Si*”
? matches 1 character only

predicateWithFormat: @'SELF LIKE[c] %@', 'Silv?'

Will return “Silva”, “silva”, “Silvy”

Quick tips

CFStringTransform normalizes strings if diacritic insensitive isn’t enough. For example you could turn Japanese characters into a Latin alphabetic representation. It’s extremely powerful with a lot of methods that you can see here:http://nshipster.com/cfstringtransform/

Make sure your columns are indexed to improve performance of using IN operators

[c] case insensitive: lowercase & uppercase values are treated the same

[d] diacritic insensitive: special characters treated as the base character

predicateWithFormat: @'name CONTAINS[c] 'f'

Keypath collection queries

Keypath collection queries work best when you work with a lot of numbers. Being able to call the min or max, adding things up, and then filtering results are simpler when you only have to append an extra parameter. By having an array of expenses, you can do a quick check on if something is below or above a range of allowed expenses.

[NSPredicate predicateWithFormat:@'[email protected] < 200']

How subqueries work

A subquery takes a collection then iterates through each object (as variableName) checking the predicate against that object. It works well if you have a collection (A) objects, and each object has a collection (B) other objects. If you’re trying to filter A based on 2 or more varying attributes of B.

predicateWithFormat: @'SUBQUERY(tasks, $task, $task.completionDate != nil AND $task.user = 'Alex')[email protected] > 0'

SUBQUERY(…) returns an array. We need to check if its count > 0 to return the true or false value predicate expects.

About the content

This content has been published here with the express permission of the author.


Realm Team

At Realm, our mission is to help developers build better apps faster. We provide a unique set of tools and platform technologies designed to make it easy for developers to build apps with sophisticated, powerful features — things like realtime collaboration, augmented reality, live data synchronization, offline experiences, messaging, and more.

Everything we build is developed with an eye toward enabling developers for what we believe the mobile internet evolves into — an open network of billions of users and trillions of devices, and realtime interactivity across them all.

14 minute read

Updated for Xcode 12

Shortly after Apple’s “Hey Siri” event the Xcode 7 GM was released to developers. Let’s put the betas behind us and take a look at some real world UI Testing examples.

The examples all use a test host that helps you manage your volleyball team. The app, Volley, lets the user manage the team roster, adjust the formation, and view game results. Feel free to take a look at the source code before continuing along to familiarize yourself with how it works.

Why not use recording?

You can certainly use the recording feature of UI Testing on its own. Recording makes sense when adding regression tests to an existing codebase. But you’ll miss out on the perks of writing your own tests. However, there are three reasons why recording isn’t always the best idea.

  1. With test-driven development you write your tests first, so you won’t have an app to record!
  2. Recording doesn’t always work. Recording interaction with some elements, such as web views, never works, and UISlider manipulation is finicky at best.
  3. The most important reason to learn UI Testing by hand is to, well, learn it yourself! At some point you will need to read the code generated by Xcode and debug it. If you can’t figure out what is going on you are going to have a hard time deciphering where something went wrong. Also, if you are using any custom controls you will need to write the tests yourself.

Basic functionality

Nspredicate

These code snippets assume you are familiar with the basics of UI Testing. If you are just getting started, or would like a refresher, I suggest reading an overview of UI Testing in Xcode.

The examples also assume that your app is launched and you hold a reference to it, app. You can do this in your test class’ setUpWithFailure() method to ensure the app launches clean for every test.

How to assert an element exists

Let’s start off simple. The first thing you will do when validating your app with UI Testing is asserting if an element exists. This is easily done by querying for an element and asking if it exists.

Using Volley’s home screen we can assert that the app’s name exists like so. Note the wrapping of the call in an XCTest assertion. This ensures that the test would fail if the label were not to exist.

How to wait for an element to appear

Viewing our schedule in Volley shows us our last couple of game results. Alright, 2-1! Not a bad start to the season. But when’s our next game?

Tapping the Load More Games button simulates fetching data from a server. After two seconds pass, our fourth game comes back.

If five seconds pass before the expectation is met then the test will fail.

How to print the accessibility hierarchy

Printing the accessibility hierarchy is a good way to “see what the framework sees.” You can use this and the Accessibility Inspector to debug querying and selecting elements

Interacting with system controls

Beyond validating and verifying basic conditions, you will want to interact with your app. XCUIElement exposes a few crucial functions to help us tap around the interface. These method use a XCUIElementQuery to find the element by its accessibility label or identifier.

How to tap a button

Nspredicate Cheat Sheet

How to type text into a text field

Typing into a text field requires that the target has focus. Simply tapping on it will ensure the text field is the first responder.

How to dismiss an alert

First find the alert by querying for its title. You can then reference its buttons by chaining on the selector and tapping which one you want.

You can try this in Volley by going to the Schedule screen and tapping on the “Finish Game” button.

How to interact with a system alert

Ah, system alerts, the bane of all iOS testers’ existence. Almost every other framework I’ve worked with has had issues with system alerts, whether it’s location services, push notifications, or access to your photos.

With UI Testing we can finally reliably interact with these pesky dialogs. There are, however, two small gotchas.

First, set up a “UI Interuption Handler” before presenting the alert. This is our way of telling the framework how to handle an alert when it appears.

Second, after presenting the alert you must interact with the interface. Simply tapping the app works just fine, but is required.

How to slide a slider

When adjusting a UISlider with UI Testing you don’t pass in the value you want to set. Instead, you normalize the value on a scale from 0 to 1. For example, the slider in Volley has a range of 0 to 10. To slide the scrubber to 7 we pass in 0.7, or, how I like to think of it, 70%.

How to select an item from a picker

XCUIElement has a special method for interacting with UIPickerViews. For a picker with only one wheel, we can access it via element() then just adjust to our specified value.

Picker with one wheel

Picker with multiple Wheels

If the picker is more complex with multiple wheels we have a little set up to do. We need a way to identify the different wheels to the framework. Conforming to the UIPickerViewAccessibilityDelegate provides the right interface to set accessibility text on each picker.

This then sets the first wheel’s accessibility title to “Attackers Formation, 4 attackers.” Notice how the selected value sneaks in? To actually select the element we will need to match it with a BEGINSWITH predicate.

How to tap links in a web view

Nspredicate Cheat Sheet Printable

There’s nothing too exciting going on here, which leads to a clean API. The tap() method can be used with both UIWebView and WKWebView.

Complex interactions

How to assert a view is on the screen

One weird behavior of exists() is that it returns true even if the element is off the screen. You have to jump through some hoops to make sure the element is actually visible to the user.

We can test this by asserting that the element’s frame is contained in the window’s frame with CGRectContainsRect().

How to reorder table cells

Open up the Accessibility Inspector and hover over the Manage Roster screen. The little reordering icons automatically get their own accessibility titles based on the cell that they are contained in. Here the cell’s label is “Adrienne,” so the icon’s identifier becomes “Reorder Adrienne.”

We can now use these to drag cells up and down.

How to “pull to refresh”

To replicate this gesture we need to drop into the XCUICoordinate API. You can use these objects to interact with specific points on the screen, not necessarily tied to any particular element. This becomes very useful when we want to drag an element to a specific location.

First, grab a reference to the first cell in your table. Then create a coordinate with zero offset, CGVectorMake(0, 0). This will normalize a point right on top of the first cell.

Nspredicate Cheat Sheet Template

Using this point we can create an imaginary coordinate farther down the screen. I’ve found that a dy of six is the smallest amount needed to trigger the pull-to-refresh gesture.

We can then execute the gesture by grabbing the first coordinate and dragging it to the second one.

What else?

Looking for a specific technique or notice something is missing? Leave a comment below or reach out to me on Twitter. I’m more than happy to add it to the post!

Testing, development, and product sneak peeks.
Sign up for my monthly newsletter.