Skip to content

iOS Tutorial Part 2: Queries

nickelskevin edited this page Apr 23, 2014 · 1 revision

In Tutorial Part I, we created a test class, one model class and two scenes that demonstrated basic CRUD functionality with complex model objects as well as authentication.

If you wish, you can download the complete Part II project file from Download Tutorial Part 2 Sample Files, unzip and then either run newapp again from this directory to use this application or copy the files that are enclosed to the application directory you created in a previous section Installing FatFractal allowing the copy to replace all the previous files.

If you have not scaffolded your app already, it is not a problem, just run ffef newapp, using your domain, as before from the directory with the Part II files you have just downloaded and it will set up all the things that you need.

> $HOME/ff/ffnsbin/ffef newapp hoodyoodoo <your domain>

Note: The domain refers to the organization name you signed up with, e.g. acme in acme.fatfractal.com

Note: When you download the project, the client application is configured to use a backend that is already deployed and populated with data. This means you can run the application on your simulator immediately. To use your backend, you should edit the Hoodyoodoo.java file as before to point to the backend that you have set up.

In Tutorial Part II, we will to streamline retrieving objects such that we only transfer the required data to the client. To do that we will use a query. Then we will begin to add the game mechanic to the WouldYaViewController. The design is that we will present two random and unique celebrities of the gender the player chooses, and when selected, create a record which we will call a “WouldYa” and store that in the back-end. In order to do that, we need to do the following:

  1. Retrieve a random Celebrity of the selected gender using a query.
  2. Retrieve a second random Celebrity of the selected gender that is different from the first one using a more complex query.
  3. Add a new model class called “WouldYa” to our back-end.
  4. Add the CRUD method to WouldYaViewController to persist our WouldYa to the back-end.
Retrieve a random Celebrity

Retrieve all Celebrities

To recap, Part I showed you how to retrieve all objects of a certain class from the back-end using the getArrayFromUrl: error: method.

[code language="obj-c"] NSArray *celebArray = [[FatFractal main] getArrayFromUrl:[NSString stringWithFormat:@"/ff/resources/Celebrity"] error:&error]; [/code]

And we used the following to pick out a random Celebrity from celebArray and set it to leftCelebritywhich resulted in a major performance issue with large numbers of Celebrity objects.

[code language="obj-c"] int r = arc4random() % [celebArray count]; leftCelebrity = [celebArray objectAtIndex:r]; [/code]

This is not efficient as we would retrieve all Celebrity objects, along with their images to the client application, and then force the client code to extract what it needs. If there were thousands of Celebrities in the datastore, this would be a huge load on the backend, the network and the client.

Retrieve a single random Celebrity

So, we need a better way to filter the result set on the backend. FatFractal features an elegant method of filtering results using queries expressed as natural language strings. For example, if we wanted to retrieve a random Celebrity from the back-end, we write a query as follows: In the loadCelebrities method:
    1. Change the method from getArrayFromUrl to getObjFromUrl since we only want to retrieve one object after all.
    2. Add a query to the request in the form: /(guid eq random(guid)) that will return a single random Celebrity.

[code language="obj-c"] leftCelebrity = [[FatFractal main] getObjFromUrl:[NSString stringWithFormat: @"/ff/resources/Celebrity/(guid eq random(guid))"] error:&error]; [/code]

This will return a single random Celebrity which is far more efficient for both the backend as well as the client code.

Retrieve a single random Celebrity filtered by gender parameter

For our application, we need to do also filter by gender,  which will be selected by the user. To do that we need to be able to pass parameters in to the query. This is easily done by constructing the query string using NSString stringWithFormat as shown below and pass in the desired parameter(s).

[code language="obj-c"] leftCelebrity = [[FatFractal main] getObjFromUrl:[NSString stringWithFormat: @"/ff/resources/Celebrity/(gender eq '%@' and guid eq random(guid))", currentGender] error:&error]; [/code]

Note: since this is the first of two Celebrities that we wish to retrieve, we will use an asynchronous method that will allow both to be loaded at the same time.

Retrieve a second Celebrity filtered by gender parameter and not equal to the first Celebrity

Now, to complete loadCelebrities, we add the code to get the second Celebrity. This will use the FatFractal metaDataForObj method to get the guid from the meta data supplied by the back-end along with leftCelebrity and pass the guid a as a parameter for another query that will make sure that the two Celebrities are unique.

[code language="obj-c"] rightCelebrity = [[FatFractal main] getObjFromUrl:[NSString stringWithFormat: @"/ff/resources/Celebrity/(gender eq '%@' and guid ne '%@' and guid eq random(guid))", currentGender, [FatFractal main] metaDataForObj:leftCelebrity] guid error:&error]; [/code]

NEXT: The WouldYa Class