Objectively Speaking 2: A Crash Course in Objective-C for iOS 6

This is the 2nd post by iOS Tutorial Team Member Linda Burke, an indie iOS developer and the founder of canApps. If you are a software developer skilled in another platform, but want to start learning iPhone development (and hence Objective-C) – this is the tutorial series for you! This tutorial picks up where the […] By .

Leave a rating/review
Save for later
Share
You are currently viewing page 3 of 6 of this article. Click here to view the first page.

Creating the Property List File

Go to File\New File…, choose the iOS\Resource\Property List template, and click Next. Select the location to save your new file and name the file quotes.

Right-click on the quotes file in your Project Navigator and select Open As\Source Code. Now, add your movie quotes by copying and pasting the following code into quotes:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!--
 Quotes
 -->
<plist version="1.0">
    <array>
        
        <dict>
            <key>category</key>  <string>classic</string>
            <key>quote</key>  <string>Frankly my dear, I don't give a damn.</string>
            <key>ans1</key>  <string>Gone with the wind</string>
            <key>ans2</key>  <string>Casablanca</string>
            <key>ans3</key>  <string>Pride and Prejudice</string>
            <key>answer</key>  <string>1</string>
            <key>tip</key>  <string>Check the weather.  Is that a North-Westerly blowing?</string>
        </dict>
        
        <dict>
            <key>category</key>  <string>classic</string>
            <key>quote</key>  <string>Here's looking at you kid.</string>
            <key>ans1</key>  <string>The rear window</string>
            <key>ans2</key>  <string>To Kill a Mockingbird</string>
            <key>ans3</key>  <string>Casablanca</string>
            <key>answer</key>  <string>3</string>
            <key>tip</key>  <string>Moroccan tea anyone?</string>
        </dict>
        
        <dict>
            <key>category</key>  <string>classic</string>
            <key>quote</key>  <string>There's no place like home.</string>
            <key>ans1</key>  <string>Vertigo</string>
            <key>ans2</key>  <string>Wizard of Oz</string>
            <key>ans3</key>  <string>Singin in the rain</string>
            <key>answer</key>  <string>2</string>
            <key>tip</key>  <string>Be aware of the wicked witch.</string>
        </dict>
        
        <dict>
            <key>category</key>  <string>classic</string>
            <key>quote</key>  <string>Elementary my dear Watson.</string>
            <key>ans1</key>  <string>Sherlock Holmes</string>
            <key>ans2</key>  <string>The African Queen</string>
            <key>ans3</key>  <string>High Noon</string>
            <key>answer</key>  <string>1</string>
            <key>tip</key>  <string>It is mystery, this one.</string>
        </dict>
        
        <dict>
            <key>category</key>  <string>classic</string>
            <key>quote</key>  <string>Fasten your seatbelts. It's going to be a bumpy night.</string>
            <key>ans1</key>  <string>The Graduate</string>
            <key>ans2</key>  <string>All about Eve</string>
            <key>ans3</key>  <string>West Side Story</string>
            <key>answer</key>  <string>2</string>
            <key>tip</key>  <string>The birds and the bees.</string>
        </dict>
        
        <dict>
            <key>category</key>  <string>classic</string>
            <key>quote</key>  <string>I have not the pleasure of understanding you.</string>
            <key>ans1</key>  <string>Pride and Prejudice</string>
            <key>ans2</key>  <string>Jane Eyre</string>
            <key>ans3</key>  <string>Rebecca</string>
            <key>answer</key>  <string>1</string>
            <key>tip</key>  <string>I have high self esteem.</string>
        </dict>
        
               
        <dict>
            <key>category</key>  <string>classic</string>
            <key>quote</key>  <string>That's, uh, quite a dress you almost have on...What holds it up?</string>
            <key>ans1</key>  <string>It happened one night</string>
            <key>ans2</key>  <string>Roman Holiday</string>
            <key>ans3</key>  <string>An American in Paris</string>
            <key>answer</key>  <string>3</string>
            <key>tip</key>  <string>Fancy a baguette?</string>
        </dict>
        
        <dict>
            <key>category</key>  <string>classic</string>
            <key>quote</key>  <string>Love, desire, ambition, faith - without them life is so simple, believe me</string>
            <key>ans1</key>  <string>Easy Rider</string>
            <key>ans2</key>  <string>Invasion of the Body Snatchers</string>
            <key>ans3</key>  <string>Wuthering Heights</string>
            <key>answer</key>  <string>2</string>
            <key>tip</key>  <string>Danger, Danger.</string>
        </dict>
        
        <dict>
            <key>category</key>  <string>modern</string>
            <key>quote</key>  <string>Go ahead make my day.</string>
            <key>ans1</key>  <string>Dirty Harry</string>
            <key>ans2</key>  <string>Star wars</string>
            <key>ans3</key>  <string>Terminator</string>
            <key>answer</key>  <string>1</string>
            <key>tip</key>  <string>Get some soap.</string>
        </dict>
        
        <dict>
            <key>category</key>  <string>modern</string>
            <key>quote</key>  <string>May the Force be with you.</string>
            <key>ans1</key>  <string>One flew of the cuckoo's nest'</string>
            <key>ans2</key>  <string>Top Gun</string>
            <key>ans3</key>  <string>Star wars</string>
            <key>answer</key>  <string>3</string>
            <key>tip</key>  <string>It's a bright moon tonight.'</string>
        </dict>
        <dict>
            <key>category</key>  <string>modern</string>
            <key>quote</key>  <string>Hasta la vista, baby</string>
            <key>ans1</key>  <string>Harry Potter</string>
            <key>ans2</key>  <string>Terminator</string>
            <key>ans3</key>  <string>Pirates of the Carribean</string>
            <key>answer</key>  <string>2</string>
            <key>tip</key>  <string>The main character is an emotionless and efficient killing machine.</string>
        </dict>
        <dict>
            <key>category</key>  <string>modern</string>
            <key>quote</key>  <string>I feel the need for speed.</string>
            <key>ans1</key>  <string>Top Gun</string>
            <key>ans2</key>  <string>Twilight</string>
            <key>ans3</key>  <string>Speed</string>
            <key>answer</key>  <string>1</string>
            <key>tip</key>  <string>Flying high.</string>
        </dict>
        <dict>
            <key>category</key>  <string>modern</string>
            <key>quote</key>  <string>She doesn't even go here.</string>
            <key>ans1</key>  <string>St Trinians</string>
            <key>ans2</key>  <string>Wild Child</string>
            <key>ans3</key>  <string>Mean Girls</string>
            <key>answer</key>  <string>3</string>
            <key>tip</key>  <string>No one likes a bully.</string>
        </dict>
        <dict>
            <key>category</key>  <string>modern</string>
            <key>quote</key>  <string>It takes a great deal of bravery to stand up to your enemies, but a great deal more to stand up to your friends.</string>
            <key>ans1</key>  <string>Pirates of the Carribean</string>
            <key>ans2</key>  <string>Harry Potter</string>
            <key>ans3</key>  <string>Toy Story</string>
            <key>answer</key>  <string>2</string>
            <key>tip</key>  <string>Cast a spell on me.</string>
        </dict>
        <dict>
            <key>category</key>  <string>modern</string>
            <key>quote</key>  <string>I solemnly swear that I am up to no good.</string>
            <key>ans1</key>  <string>Harry Potter</string>
            <key>ans2</key>  <string>Shrek</string>
            <key>ans3</key>  <string>The Lion King</string>
            <key>answer</key>  <string>1</string>
            <key>tip</key>  <string>Cast another spell on me.</string>
        </dict>
        
        <dict>
            <key>category</key>  <string>modern</string>
            <key>quote</key>  <string>You like pain? Try wearing a corset.</string>
            <key>ans1</key>  <string>Spy kids</string>
            <key>ans2</key>  <string>Shrek</string>
            <key>ans3</key>  <string>Pirates of the Carribean</string>
            <key>answer</key>  <string>3</string>
            <key>tip</key>  <string>Aye, Aye, captain.</string>
        </dict>       
    
    </array>
</plist>

Property lists can be tiresome to debug, but you can easily use Xcode to validate your property list file to make sure that you haven’t missed a closing tag somewhere.

In Xcode, select Xcode\Product\Build For -> Running. If you see no compilation errors, you can be sure that your property list is solid, and you can continue on with the road trip!

Iterating Through the Property List

Now you need to implement the code that retrieves the next quote for the quiz.

Modify Quiz.h so that it looks the following:

#import <Foundation/Foundation.h>

@interface Quiz : NSObject

@property (nonatomic, retain) NSMutableArray * movieArray; // Previous Property
@property (nonatomic, assign) NSInteger correctCount;
@property (nonatomic, assign) NSInteger incorrectCount;
@property (nonatomic, assign) NSInteger quizCount;
@property (nonatomic, readonly, strong) NSString * quote;
@property (nonatomic, readonly, strong) NSString * ans1;
@property (nonatomic, readonly, strong) NSString * ans2;
@property (nonatomic, readonly, strong) NSString * ans3;

-(id) initWithQuiz:(NSString*)plistName; // Previous Method
-(void) nextQuestion: (NSUInteger) idx;
-(BOOL) checkQuestion: (NSUInteger) question forAnswer: (NSUInteger) answer;

@end

The properties and methods declared above will support the retrieval of questions and answers in your quiz. The Quiz object also keeps track of the number of correct and incorrect questions, as well as the total number of questions that were asked.

The methods above are publicly accessible because you’ve declared them in your header file. However, if you have methods in your implementation that are private and used only internally by your implementation code, then you don’t need to declare them in your header.

Okay, now you’ll start fleshing out your implementation.

Add the following code to Quiz.m before the @implementation line:

@interface Quiz()
    @property (nonatomic, strong) NSString * quote;
    @property (nonatomic, strong) NSString * ans1;
    @property (nonatomic, strong) NSString * ans2;
    @property (nonatomic, strong) NSString * ans3;
@end

Hey, those property definitions look familiar! They’re almost the same as the ones you defined in your header file. The only difference is that these definitions don’t include the readonly keyword. What gives?

This is known as a class extension, which gives you the ability to read and write to these properties locally inside your implementation. But to the rest of the world, these properties still appear read-only.

Okay, now that all of the properties you need are in place, it’s time to put them to use!

Add the following code to Quiz.m after the @implementation line:

- (void) nextQuestion: (NSUInteger) idx 
{    
    self.quote = [NSString stringWithFormat:@"'%@'",self.movieArray[idx][@"quote"]];
    
    self.ans1 = self.movieArray[idx][@"ans1"];
    self.ans2 = self.movieArray[idx][@"ans2"];
    self.ans3 = self.movieArray[idx][@"ans3"];
    
    if (idx == 0) {
        self.correctCount = 0;
        self.incorrectCount = 0;
    }
}

nextQuestion sets the internal values of the quiz object. It reads in a quote and three possible answers from movieArray, which contains all the data loaded from your property list.

If this is the first question of the quiz, then the app resets the quiz totals just in case the user want to play through the quiz again to beat their previous high score!

Now, how are you going to determine if the answer the player gives is right or wrong? checkQuestion can do that work for you.

Add the following code to Quiz.m just before @end:

- (BOOL) checkQuestion: (NSUInteger) question forAnswer: (NSUInteger) answer
{
    NSString * ans = self.movieArray[question] [@"answer"];   
    if  ([ans intValue] == answer) {
        self.correctCount++;
        return YES;
    } else  {
        self.incorrectCount++;
        return NO;
    }
}

checkQuestion takes an input parameter (NSUInteger) question as the index of the correct question. If the answer the player gives matches the correct answer, then correctCount is incremented; otherwise incorrectCount is incremented.

Finally you need to to keep track of the number of rows in the array.

Inside Quiz.m, modify initWithQuiz by adding a line to set self.quizCount, as shown below:

if ((self = [super init]))
{
    NSString *plistCatPath = [[NSBundle mainBundle] pathForResource:plistName ofType:@"plist"];
    self.movieArray = [NSMutableArray arrayWithContentsOfFile:plistCatPath];
    self.quizCount = [self.movieArray count];
}