cnet w3school filehippo wikipedia yahoo google google google google google google google google google google WELCOME. Thanks for visiting our site. Comment an advise for the development of the site
Related Posts Plugin for WordPress, Blogger...

iphone app programming tutorial

Leave a Comment

The goal of this tutorial is to give you confidence with some of the basics of Objective-C. Instead of taking a “let’s explain every piece of syntax” approach, we’re going to take the approach of diving right in and giving you some hands-on experience and an example to work from. It will then be a lot easier for you to consult a reference when necessary moving forward.
In this tutorial, you will create a simple app that randomly generate quotes from a stored list. In doing so, you’ll become acquainted with a number of aspects of Objective-C, including:
  • Variables
  • Arrays
  • Property lists
  • Strings
  • Predicates
  • Random selection
  • Simple interface objects and events
Let me warn you though – iPhone development with Objective-C is a lot of fun and a little addictive. Be prepared to give up some sleep, and the chores might build up! :]
Before you begin, make sure you have an Apple developer account with the provisioning details set up and the latest version of Xcode installed (you can download this for free on the Mac App Store).
When you’re done, I will (Objective) C-you after the jump! :]

Getting Started

First things first: create an Xcode project.
Start up Xcode and create a new project with the iOS\Application\Single View Application template. Then click Next.
Enter “QuoteGen” for the product name, enter your default company identifier, set device family to iPhone, and make sure Use Automatic Reference Counting is checked (but leave the other checkboxes unchecked). Now click Next and select the location to save your project.
You will notice that your project has been created with AppDelegate.hAppDelegate.m,ViewController.h and ViewController.m files, as well as a ViewController.xib.
>
The AppDelegate contains the code that initiates the app. For this tutorial, that’s all you need to know. Here are brief explanations of the other files, with which you will be working directly:
  • ViewController.xib (XIB file for short) is the interface layout file. You visually create/design the screen that’s displayed on the iPhone device using this file.
  • ViewController.m is the interface controller class. The interface layout file is linked to this class. This happens automatically, so at this stage you don’t need to think about it other than to know that any objects or events you set up in your interface class can be linked to your interface layout very easily. This is the file that will contain the Objective-C code you’re about to create.
  • ViewController.h is the interface controller class header file, where you’ll declare the instance variables, as well as the objects and events that you need to access from the interface screen.
Note: There are two ways to create interfaces in Xcode – with XIBs and with Storyboards. Either way works fine, in this tutorial we’ll be using XIBs but if you want to try out Storyboards check out this tutorial when you’re done.

Heading in the Right Direction

Start by creating the property declarations for the variables you’ll need to store your quotes. You ought to know by now where to add these variables. Yep, the class header file, ViewController.h! Add an array as follows between the @interface and @end lines:
@property (nonatomic, retain) NSArray *myQuotes;
The property directive tells the compiler that the variable myQuotes is a property of this class. Without going too deeply into this topic – the complexities of memory management are for another day – the attributesnonatomic and retain are widely used for efficiency. The monatomic attribute specifies that the property might not work in a multi-threaded environment and retain indicates that a pointer to the specified variable will stay in memory as long as the ViewController object exists.
Note: FYI the retain keyword is synonymous with strong. In Objective-C, you used to have to do all the memory management yourself, but now with a new feature called ARC it’s automatic. To read more about ARC, check out this tutorial.
This app is also going to store some famous quotes from movies. For this, you need a second array:
@property (nonatomic, retain) NSMutableArray *movieQuotes;
Here you’re using an NSMutableArray simply to illustrate the different types of arrays. More about that later.

Manual Labor

Now you need to synthesize the arrays – this is a way to let the compiler know that it should synthesize the setter and/or getter methods for a property if you do not supply them within the @implementation block.
Do the above by editing ViewController.m and adding these two lines after the @implementation line:
@synthesize myQuotes;
@synthesize movieQuotes;
@synthesize provides default methods for getting and setting the contents of the objects. In simple terms, these methods allow you to add data to the array and retrieve it for display.
Now you can store your favorite quotes in the myQuotes array. Do this in viewDidLoad, the method that executes when the view (screen) is displayed. There’s no need to do it more than once, as the quote list won’t change, so viewDidLoad is a good place.
In viewDidLoad, add the following code after [super viewDidLoad];. Include your own favorite quotes if you like. This is the “manual labor” approach and is quite okay for a small number of array entries.
// 1 - Add array of personal quotes
self.myQuotes = [NSArray arrayWithObjects:
                      @"Live and let live", 
                      @"Don't cry over spilt milk", 
                      @"Always look on the bright side of life", 
                      @"Nobody's perfect", 
                      @"Can't see the woods for the trees",
                      @"Better to have loved and lost than not loved at all",
                      @"The early bird catches the worm",
                      @"As slow as a wet week",
                      nil];
This is the first example of calling a method. The syntax is a bit different than what you might be used to in other languages:
  • To begin calling a method, you put a bracket and then the name of the object you want to call a method on. In this case, we’re calling a (static) method on NSArray.
  • You then put the (first part) of the name of the method, and a colon. In our case, this is arrayWithObjects.
  • You then add the first parameter. This method is kinda a special case because this is a variable-length parameter method, so we can pass a list of objects to add to the array, and put nil when we’re done.
  • If the method has multiple parameters, you’d continue on in this manner. This method just has one parameter though (the list of objects).
If you’re still hung up on the syntax, don’t worry – we’ll see plenty more examples of calling methods soon.
Also notice that in Objective-C, when you use strings you put an @ symbol before them. If you’re used to other languages, this can be easy to forget, which will probably cause your app to crash :] So if your app crashes when it uses a string, double check you remembered to use the @ symbol!
SELF HELP
Use “self” when setting and getting data for a property. This is similar to the “this” keyword in other languages, and refers to the object upon which the method is running.
You can access instance variables directly (without self), but by using self you go through the getters and setters for the instance variables. Until you know learn the reasons you might want to use instance variables directly, a good rule for beginners is to always use self.
Every time you add assign to a retained property, make sure you clear it out in ViewDidUnload as follows (add the code below the existing line):
movieQuotes=nil;
myQuotes=nil;
This is important so that when the view is unloaded (which happens in low memory situations when the view is not visible), your quotes array can be freed as well. Basically you typically want to do the opposite of whatever you do in viewDidLoad. It’s a good thing to free up memory when it’s low! :]
OK, now that we have these quote arrays set up, let’s try them out!
First, declare the interface elements and actions that you’ll hook in to in the XIB file. Add the following toViewController.h under the arrays:
@property (nonatomic, retain) IBOutlet UITextView *quote_text;
 
-(IBAction)quote_btn_touch:(id)sender;
The IBOutlet keyword means that quote_text is an object that can be linked to an interface element on the XIB file so that the view controller can access (or change) properties of the interface element. In this case, we’ll be setting the displayed text for the UITextView control but we could just as easily change the color, font, size, etc.
The IBAction keyword indicates that quote_btn_touch is an action that can be linked to an event for a UI control on the screen. In this case, we will be connecting to the quote button touched event.
In case you’re wondering, id means “any object that derives from NSObject”. Usually when you set up callbacks that buttons and other controls will call, they pass whatever button/control is sending the callback as the first parameter. Since we don’t necessarily know what type it is, we put id here.
Once again, you need to synthesize the new property you added. In ViewController.m, add:
@synthesize quote_text;
And don’t forget to clear out the property in ViewDidUnload:
quote_text=nil;
Now create the action method, quote_btn_touch, that is executed when the quote button is touched. Add this to the end of the file (but above @end):
-(IBAction)quote_btn_touch:(id)sender {
 // 1 - Get number of rows in array
    int array_tot = [self.myQuotes count];
 // 2 - Get random index
 int index = (arc4random() % array_tot);
 // 3 - Get the quote string for the index 
 NSString *my_quote = [self.myQuotes objectAtIndex:index];
 // 4 - Display the quote in the text view
 self.quote_text.text = [NSString stringWithFormat:@"Quote:\n\n%@",  my_quote];      
}
The arc4random function is used to generate a random number. In this case, since we want to randomly select one of the quotes, the highest possible value is the number of rows in the array, and the lowest possible value is 0. In Objective-C (like many other languages), the first row in an array is row 0, not 1.
index is just a temporary integer variable that you use to store the random number, which is then used to get that specific quote from array. As the array is a simple list of strings, you can get the quote by usingobjectAtIndex: and store the quote in a temporary variable of type string.
You then use the temporary string variable my_quote to set the displayed text for the quote_text control on the screen.
You use the stringWithFormat method to format the final output string so that you can display a label and add a new line before displaying the quote. It uses variable substitution, like printf in C/C++. %f is float, %d is integer, and %@ is Objective-C object.
Now in order to actually see the quote on the screen, you need to link the text field outlet in the class with a text field control in your XIB file.

We Have Lift Off!

To see it all in action, open up ViewController.xib. Next, look for the right sidebar in your Xcode window. If you don’t see one, you might need to use the rightmost button under the Views section, on the toolbar at the top, to make the right hand sidebar visible.
The lower part of the righthand sidebar has four tabs, which you can switch between using the icons at the top of that section. The section you want is the Object Library.
From the Object Library, drag a Text View control and a Round Rect Button onto the view. Position them to your liking. Add a title to the button, such as “Quote”. Change the color and font for the controls as you see fit. You can change most properties for the controls via the upper part of the right hand sidebar which too has several tabs that you can switch between – the one you’ll use the most to customise the appearance of the controls is the Attributes Inspector tab.
As the text field is for display only, untick Behavior – Editable.
Now you need to link the button and the text view to the outlet and action you already set up in your class.
Link your text view by right-clicking the text view, clicking on the New Reference Outlet circle, dragging to File’s Owner and selecting quote_text.
Alternatively, you can simply select File’s Owner and then switch the top portion of the right hand sidebar to the Connections Inspector tab. You should see all the connections available for your File’s Owner, which happens to be your controller class. You can now simply drag from the available connection to the control visible on screen.
Now, you can programmatically set the value for the text displayed in the text view by modifying quote_text.
Similarly, we can hook up touch events on the button we added to the XIB file to the quote_btn_touch action we set up earlier. To do that, right-click on the button and drag Touch Up Inside to Files’s Owner and select quote_btn_touch.
Alternatively, you can simply select the button in the XIB view, and if you have the Connections Inspector selected in the right hand sidebar, you’ll notice that you get a list of events for the button. Now drag from the Touch Up Inside event to the File’s Owner and you should get a list of possible actions you can connect that event to. Just select the one you want.
Guess what? You’re ready to rock ‘n’ roll. Simply click on the Xcode Run button (the first button at the top of the screen) to compile and run your app in the simulator.
If there are errors, don’t panic. At this stage, they should be self-explanatory. Often just typos when declaring your variables. Remember, Xcode is case-sensitive.
If your app does compile and run, then click on the Quote button to get a random quote. Not having many quotes in the list limits the excitement a little. But don’t worry, you’re about to load up another array and with this one you can go wild and add as many quotes as you like, because they won’t be in the code.
“How so?” you ask?
Ah, the joys of property lists are about to be revealed! I’m a big fan of property lists.

Property Lists Rule!

Create a new file with the iOS\Cocoa Touch\Objective-C class template. Name the class SMNote, and make it a subclass of UIDocument.
Create a new file by right-clicking on your project root on the left sidebar (the Project Navigator) and select “New File …” Then select iOS\Resource\Property List and click “Next”. Select the location to save your new file (usually somewhere within the project folder for the tutorial project) and name the file “quotes”.
You can either edit the property list file from within Xcode in a grid-view (as a list of properties) or as a text file. If you want to edit as a text file, right-click on the quotes file on the Project Navigator and select Open As\Source Code.
Since we want to quickly add all the quotes by copying and pasting, opening as source code probably would be the faster route. If you want though, you can try the grid view approach and try to figure out how to add the same values as below using that method.
Now, add your movie quotes by copying and pasting the following into quotes (in source code mode):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<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>source</key>  <string>Gone With the Wind</string>
        </dict>
 
        <dict>
            <key>category</key>  <string>classic</string>
            <key>quote</key>  <string>Here's looking at you, kid.</string>
            <key>source</key>  <string>Casablanca</string>
        </dict>
 
        <dict>
            <key>category</key>  <string>classic</string>
            <key>quote</key>  <string>There's no place like home.</string>
            <key>source</key>  <string>The Wizard of Oz</string>
        </dict>
 <dict>
  <key>category</key>  <string>classic</string>
        <key>quote</key>  <string>Play it again, Sam.</string>
        <key>source</key>  <string>Casablanca</string>
 </dict>
     <dict>
  <key>category</key>  <string>classic</string>
        <key>quote</key>  <string>Elementary, my dear Watson.</string>
        <key>source</key>  <string>Sherlock Holmes</string>
 </dict>
 
        <dict>
            <key>category</key>  <string>modern</string>
            <key>quote</key>  <string>Go ahead, make my day.</string>
            <key>source</key>  <string>Dirty Harry</string>
        </dict>
 
        <dict>
            <key>category</key>  <string>modern</string>
            <key>quote</key>  <string>May the Force be with you.</string>
            <key>source</key>  <string>Star Wars</string>
        </dict>
        <dict>
            <key>category</key>  <string>modern</string>
            <key>quote</key>  <string>Hasta la vista, baby.</string>
            <key>source</key>  <string>Terminator 2: Judgement Day</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>source</key>  <string>Harry Potter and the Sorcerer's Stone</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>source</key>  <string>Harry Potter and the Prisoner of Azkaban</string>
        </dict>
 
        <dict>
            <key>category</key>  <string>modern</string>
            <key>quote</key>  <string>You like pain? Try wearing a corset.</string>
            <key>source</key>  <string>Pirates of the Caribbean</string>
        </dict>
    </array>
</plist>
These are just a few quotes to serve as examples. Have some fun and add your own favorites. If you’re feeling lazy, the sample project has a property list of many quotes.
The quotes are categorized as either classic or modern to illustrate a really neat feature that we’ll get to a bit later.
You can also switch over to the Property List view (right-click on the quotes file on the Project Navigator and select Open As\Property List) to see how the values you added look in the grid view and how it is organised. Now that you know how the different editing modes work, you can always switch back and forth as you like.
Property lists are cool, but can be very uncool when you get an error. Common mistakes for newbies are forgetting the end tag or accidentally deleting a < or >. If your property list doesn’t load, then you’ll need to trawl through and work out why. Earlier versions of Xcode gave line numbers for errors. I think it was from version 4 onwards that this helpful feature was excluded.
If you really get stuck, you need to methodically go through your file. I do this (a bit too often to be frank) to make it easier: copy my plist file, then remove chunks a bit at a time to identify the approximate location of the error.
Having created your lovely property list, you are now ready to load it into an array for use. So let’s switch back to ViewController.m and add the following to the end of viewDidLoad:
// 2 - Load movie quotes
NSString *plistCatPath = [[NSBundle mainBundle] pathForResource:@"quotes" ofType:@"plist"];
self.movieQuotes= [[NSMutableArray arrayWithContentsOfFile:plistCatPath] copy];
It’s as easy as that – now you have an array with all of the movie quote data you entered in the property list!
To try out your new array, you might think that all you really need to do is change getting the random quote from your personal quotes array to the movie quotes array. So, in quote_btn_touch you simply replace all references to myQuotes with movieQuotes, right?
But that alone will not work, as you will find if you try it. This is because myQuotes was an array of quote strings. But movieQuotes is not an array of strings. Instead, it’s an array of dictionaries where a dictionary is a list of values where you can access each value based on a unique key.
Why? Because that’s how you set up the property list (go look at it again to see!)
Note: Dictionaries are key/value stores, similar to hashtables in other languages. You can look up entries in a dictionary with the valueForKey method.
So replace quote_btn_touch with the following code which switches over to using the movieQuotes array but also gets the quote by using the right key for each quote dictionary:
-(IBAction)quote_btn_touch:(id)sender {
    // 1 - Get number of rows in array
    int array_tot = [self.movieQuotes count];
    // 2 - Get random index
    int index = (arc4random() % array_tot);
    // 3 - Get the quote string for the index 
    //NSString *my_quote = [self.myQuotes objectAtIndex:index];
    NSString *my_quote = [[self.movieQuotes objectAtIndex:index] valueForKey:@"quote"];
    // 4 - Display the quote in the text view
    self.quote_text.text = [NSString stringWithFormat:@"Quote:\n\n%@",  my_quote];      
}
Keep the commented out line in section #3 as it will come in handy later. Build and run and enjoy your new movie quotes!
Now you’re going to get a bit fancy and allow the user to select between viewing myQuotes or movieQuotes, and whether to view classic or modern movie quotes.

Options, Options, Options

First you need to go back to your class header file, ViewController.h, and add a new property.
@property (nonatomic, retain) IBOutlet UISegmentedControl *quote_opt;
Here you’ve added a segmented control which allows you to select one item from a list of options – perfect for selecting a quote type.
And of course, you need to synthesize the new property. Add the following to the top of ViewController.mwhere the other @synthesize statements are:
@synthesize quote_opt;
Now go to ViewController.xib and drag a Segmented Control onto your view.
Change the properties of the control to the following:
  • Style: Bar (my personal preference)
  • Tint: whatever you like
  • Segments: 3
  • Select Segment: 0 and change the title to: Classic
  • Select Segment: 1 and change the title to: Modern
  • Select Segment: 2 and change the title to: Mine
This achieves the effect of having three different quote types – or rather, the ability to select between one of the three.
Having created your Segmented Control, you need to link it to the outlet in your class. You can use the same method as before to hook up the control to quote_opt in File’s Owner.
You will not need an action event for this control.
Before you do anything else, clear out the new property in ViewDidUnload.
quote_opt=nil;
Why don’t you build and run to see your new control on screen? It won’t do anything at the moment, but it’s nice to know it’s there!

The Joy of Predicates

A predicate is a useful object that filters an array. It’s a bit like having a select with a simple where clause in SQL. I find them quite useful when I have a categorized property list. It saves you from having to create separate property lists.
Don’t hate me, but you have to go back and change quote_btn_touch: in ViewController.m to use myQuotes instead of movieQuotes, as you will soon do something quite different for your movie quotes. And you need to put a condition around it, so that you’ll only use this when the third option is selected in the Segmented Control.
Or, if you prefer, simply replace quote_btn_touch: with the following code:
-(IBAction)quote_btn_touch:(id)sender {
    // 1 - Get personal quotes when the final segment is selected
    if (self.quote_opt.selectedSegmentIndex == 2) {
        // 1.1 - Get number of rows in array
        int array_tot = [self.myQuotes count];
        // 1.2 - Get random index
        int index = (arc4random() % array_tot);
        // 1.3 - Get the quote string for the index 
        NSString *my_quote = [self.myQuotes objectAtIndex:index];
        // 1.4 - Display the quote in the text view
        self.quote_text.text = [NSString stringWithFormat:@"Quote:\n\n%@",  my_quote];
    }
}
Now the user will see myQuotes only when they select the third option. As you’ll notice the rest of the code is the same as before, the only difference is that we display a quote (and that quote comes from the personal quote list) only when the segmented control has segment with index 2 selected. And as you might recall, since the segment control starts at index 0, index 2 means the third item.
Build and test your code to make sure that it works as you expect and that the quotes show up only when the “Mine” tab/segment is selected.
For the predicate fun, first you figure out the category you need based on the selected segment control and then use the category to create a filtered array of quotes that matches the category. Stay with me!
This is the code on the other side of the if statement in quote_btn_touch: – so simply add this to the end of the method to complete the “if” statement begun in section #1:
// 2 - Get movie quotes
else {
    // 2.1 - determine category
    NSString *selectedCategory = @"classic";
    if (self.quote_opt.selectedSegmentIndex == 1) {
        selectedCategory = @"modern";
    }
    // 2.2 - filter array by category using predicate
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"category == %@", selectedCategory];
    NSArray *filteredArray = [self.movieQuotes filteredArrayUsingPredicate:predicate];
    // 2.3 - get total number in filtered array
    int array_tot = [filteredArray count];
    // 2.4 - as a safeguard only get quote when the array has rows in it
    if (array_tot > 0) {
        // 2.5 - get random index
        int index = (arc4random() % array_tot);
        // 2.6 - get the quote string for the index 
        NSString *quote = [[filteredArray objectAtIndex:index] valueForKey:@"quote"];
        self.quote_text.text = [NSString stringWithFormat:@"Movie Quote:\n\n%@",  quote];
    } else {
        self.quote_text.text = [NSString stringWithFormat:@"No quotes to display."];
    }
}
Okay, build and run. Check that you see the right type of quote depending on your selection. If you are always getting the same type, my guess would be that you may not have linked the Segmented Control to your class.

The String Symphony

So far, so good! Now let’s explore some different string options and syntax in Objective-C.
If the quote has a source in the property list, then the app should display that as well. To check if there’s a value in a string, you can check the length of the string.
So add the following to quote_btn_touch: after the first line in section #2.6 (the first line not counting the comment, that is):
    // 2.7 - Check if there is a source    
    NSString *source = [[filteredArray objectAtIndex:index] valueForKey:@"source"];
    if (![source length] == 0) {
        quote = [NSString stringWithFormat:@"%@\n\n(%@)",  quote, source];
    }
    // 2.8 - Set display string
You get the source from the array and check that it contains a value by making sure that its length is not zero. ! represents NOT. Use == when checking if an integer is equal to a value.
Then you build a new display string by combining the quote and the source using stringWithFormat.
To make things more interesting, why don’t you display something slightly different for quotes from classic movies that will involve checking the value of the category of the selected quote?
Replace section #2.8 in quote_btn_touch: with the following:
// 2.8 - Customize quote based on category
if ([selectedCategory isEqualToString:@"classic"]) {
    quote = [NSString stringWithFormat:@"From Classic Movie\n\n%@",  quote];
} else {
    quote = [NSString stringWithFormat:@"Movie Quote:\n\n%@",  quote];
}
// 2.9 - Display quote
self.quote_text.text = quote;
This checks if the string is equal to a specific value, in this case “classic”, and customizes the label for the quote based on the category.
If you want to check for a particular movie title (or for that matter any other string attribute) starts with a particular value, you can do that too. Say you want to display some extra text if the quote is from a Harry Potter movie – add the following right above section #2.9:
if ([source hasPrefix:@"Harry"]) {
    quote = [NSString stringWithFormat:@"HARRY ROCKS!!\n\n%@",  quote];
}
As you can guess, hasPrefix is used to check if the start of the string has a particular text value.
Build and run your app to make sure that it works as you expect it to. Pay attention to the different categories and to Harry Potter movie quotes to make sure that it all works correctly.

It’s ARRAYning Quotes

Just for fun, you’re going to concatenate all your quotes together, as there aren’t many. This will illustrate how to loop through an array, which you might need to do if you want to iterate over each item in an array to process each item.
In quote_btn_touch: replace section #1 with the following:
// 1 - Display all personal quotes
if (self.quote_opt.selectedSegmentIndex == 2) {
    // 1.1 - Get array count
    int array_tot = [self.myQuotes count];
    // 1.2 - Initialize string for concatenated quotes    
    NSString *all_my_quotes = @"";
    // 1.3 - Iterate through array    
    for (int x=0; x < array_tot; x++) {
        NSString *my_quote = [self.myQuotes objectAtIndex:x];
        all_my_quotes = [NSString stringWithFormat:@"%@\n%@\n",  all_my_quotes,my_quote];
    }
    self.quote_text.text = [NSString stringWithFormat:@"%@", all_my_quotes];     
}
A for loop is used to loop through the array from row 0 to the last row. x is the counter that is used to keep track of the rows.
Now run and check the results.
One last thing. I mentioned earlier that there are different types of arrays: NSArray and NSMutableArray. So far, each has done the same job in this project.
Use an NSMutableArray if you want to modify/update it. As the name implies, a mutable array can be changed whereas a normal NSArray is static and you cannot add new items to the array or delete items from the array easily.
For example, if you wanted to update the array after a row had been selected in order to show that that quote had already been displayed, you would need an NSMutableArray.
In this project, movieQuotes is your NSMutableArray. You’re using a predicate, so you first need to find the row in movieQuotes and then update it. Add the following code after section #2.9 in quote_btn_touch::
// 2.10 - Update row to indicate that it has been displayed
int movie_array_tot = [self.movieQuotes count];
NSString *quote1 = [[filteredArray objectAtIndex:index] valueForKey:@"quote"];
for (int x=0; x < movie_array_tot; x++) {
    NSString *quote2 = [[movieQuotes objectAtIndex:x] valueForKey:@"quote"];
    if ([quote1 isEqualToString:quote2]) {
        NSMutableDictionary *itemAtIndex = (NSMutableDictionary *)[movieQuotes objectAtIndex:x];
        [itemAtIndex setValue:@"DONE" forKey:@"source"];
    }
}
You loop through the array and check each row to see if it’s the row you’re looking for. Again you use isEqualToString; this time, however, you’re comparing two string variables.
To update the row in the array, you retrieve the object for the row in question and update the object. This is starting to get a bit advanced for this tutorial, but it’s useful to know.
Since we’re updating the source string and since the source string is what is used to select quotes for each category, the row will not be included next time you use NSPredicate to filter the array. And that’s quite neat.

Where to Go From Here?

Here is a sample project with all of the code from the above tutorial.
Well, you’ve reached the end of this little project. You’ve learned how to use arrays in different ways, initiate actions from interface events, access objects via Interface Builder using a XIB file and do various string comparisons and concatenations. That is not a bad effort if this is your first iPhone app!