iOS Tutorial iOS Tutorial Part I

View the Project on GitHub FatFractal/hoodyoodoo

The WouldYaViewController

Now, set up the Scene to play the game. Start by retrieving a random Celebrity that was saved to the API and displaying it on the FirstViewController, which we will refactor to be the WouldYaViewController. What’s a WouldYa, you ask? You'll find out in part II of the Tutorial! But for now... For this Scene, refactor the FirstViewController to be called WouldYaViewController by renaming everything.

Next, modify  WouldYaViewController.h as follows:

#import "AppDelegate.h"
    #import "Celebrity.h"
    @interface WouldYaViewController : UIViewController
    @property (strong, nonatomic) Celebrity *leftCelebrity;
    - (void) loadCelebrities;
    @property (strong, nonatomic) IBOutlet UILabel     *leftCelebrityLabel;
    @property (strong, nonatomic) IBOutlet UIButton    *leftCelebrityButton;
    @end

These modifications accomplish the following:

  1. Import the Celebrity class, AppDelgate class and FatFractal class
  2. Add the properties for:
    1. the leftCelebrity object of objecttype Celebrity,which is made part of this class
    2. a UILabel with IBOutlet leftCelebrityLabel that will display the name of the celebrity
    3. a UIButton with IBOutlet leftopCelebrityButton button that will display the retrieved celebrity image
  3. Add the single method for now:
    1. loadCelebrities CRUD Retrieve the last stored Celebrity object

Then,  modify the WouldYaViewController.m as follows:

First, synthesize the necessary properties.

 @synthesize celebrityList, leftCelebrity, leftCelebrityLabel, leftCelebrityButton;

Next, we want to use a single CRUD method that will retrieve all the objects needed from the API at once.

This line of code returns all objects found at that API collection. We will create the loadCelebrities method to test this out.

- (void) loadCelebrities {
    NSError * error;
    NSArray *celebArray = [[FatFractal main]
    getArrayFromUrl:[NSString stringWithFormat:@"/ff/resources/Celebrity"]
    error:&error];
    if (error) {
        NSLog(@"WouldYaViewController loadCelebrities celebArray failed: %@", [error localizedDescription]);
        return;
    }
    if([celebArray count] == 0) {
        [leftCelebrityButton setBackgroundImage:[UIImage imageNamed:@"genericfriendicon.png"] forState:UIControlStateNormal];
        leftCelebrityLabel.text = @"No celebrities found";
        return;
    }
    int r = arc4random() % [celebArray count];
    leftCelebrity = [celebArray objectAtIndex:r];
    if(leftCelebrity) {
        leftCelebrityLabel.text = [NSString stringWithFormat:@"%@ %@", leftCelebrity.firstName, leftCelebrity.lastName];
        [leftCelebrityButton setBackgroundImage:[[UIImage alloc] initWithData:leftCelebrity.imageData] forState:UIControlStateNormal];
    } else {
        NSLog(@"WouldYaViewController loadCelebrities leftCelebrity could not find any");
    }
}

This code does the following:

  1. Retrieves all of the Celebrity objects from the API anonymously and populates the results to celebArray using a synchronous method.
  2. Handles error.
  3. Checks to see if any Celebrity object is returned.
  4. If so, it selects a random Celebrity object from celebArray and sets it to leftCelebrity .
  5. If leftCelebrity is not nil, sets the leftCelebrityLabel.text to the concatenation of leftCelebrity.firstName and leftCelebrity.lastName.
  6. Sets the background image for leftCelebrityButton to leftCelebrity.imageData directly.
  7. Finally, generates a log message if no object was found.
(sn. getting all objects at once is a very expensive operation for your API, from both client- and network-resource perspectives. We will explore how to use queries in the Tutorial Part II, to address this important development issue.)

Adding in UI Components

Next, we add the necessary UI components to the WouldYaViewController.
  1. Add a UIButton to hold the celebrity's image.
  2. Add a UITextField for celebrity's name, with a UILabel to identify it.

And the Scene should look like this:

Lastly, make sure and connect up your UIComponents in the MainStoryboard.storyboard  for the WouldYaViewController elements.

leftCelebrityLabel
Referencing Outlet to WouldYaViewController/leftCelebrityLabel

leftCelebrityButton
Referencing Outlet to WouldYaViewController/leftCelebrityButton

When you run the app, it loads and populates the WouldYaViewController Scene. Then, if everything is working right, it successfully retrieves a Celebrity object, randomly, and populates the UI.

(sn. You may notice, when this Scene loads, the end-user is not yet authenticated. Until the end-user attempts to affect data on the API, she may retrieve objects anonymously.)

Summary

In this tutorial, we have created our unit tests for all CRUD actions for a our very own Celebrity class we created as well as authentication without having to translate in and out of NSDictionary objects or use some other third party object models. We have used both synchronous as well as asynchronous methods within the tests to make sure they operate correctly.

Another key concept that we have demonstrated is the power of creating a complex object. In this case, an object with a blob (an image) that is seamlessly persisted and retrieved from the API. There is virtually no limit to the objects that you can exchange with your API. In fact, one could easily persist CelebrityViewController if one wanted to.

We have also built a Scene that Creates a Celebrity and a second one that Retrieves it. The CelebrityViewController Scene shows a nice pattern for authentication and the WouldYaViewController shows that you can retrieve objects from NoServer APIs anonymously which is very convenient for the developer and can greatly improve the end user experience with your application.

NEXT: Tutorial Part II, Using Queries