Click here to Skip to main content
16,021,211 members
Articles / Mobile Apps / iPhone

Making a simple Twitter app using iOS 5, Xcode 4.2, and storyboards

Rate me:
Please Sign up or sign in to vote.
4.70/5 (15 votes)
13 Jan 2012CPOL6 min read 192.6K   4.1K   36   36
How to use iOS 5, Xcode 4.2, and storyboards to create a simple Twitter app that will list tweets and show details about each tweet.

Download the source - 28.09 KB

Table of contents

  1. Table of contents
  2. Introduction
  3. Setting up the project
  4. The storyboard
  5. Coding the master view controller
  6. First run
  7. The segue
  8. Finishing the detail view
  9. Final run

Introduction

Let's use iOS 5, Xcode 4.2, and storyboards to make a simple Twitter app that will list tweets, and, when you click a tweet, show details about the tweet and user.

Setting up the project

In Xcode, start by creating a new project from FileNewNew Project.

Image 1

Select Master-Detail Application and click Next.

Image 2

As Product Name enter 'Twitter Test'. Make sure the Use Storyboard and Use Automatic Reference Counting check boxes are checked. Click Next.

Select where to save the project and click Create.

Image 3

Your project is now created. It has automatically set up a storyboard a master view controller and a detail view controller. The storyboard is where we will design our app – the controllers are where the programming takes place.

The storyboard

Let's open up our storyboard to see what it contains. Click on MainStoryboard.storyboard to the left and the storyboard comes up:

Image 4

This basically tells us that we have:

  1. A navigation view controller – that's the type of controller that automatically gives a Back button when you navigate from a list view down to a detail view.
  2. A master view controller – that's where we'll have our tweet list.
  3. A the detail view controller – that's where we'll have details about each tweet.

The lines between each controller are called 'segues'. We'll talk more about these later on when we handle the action when the user selects a tweet.

Let's set up our table view.

Setting up the table view

Select the table view in the tree view to the left:

Image 5

And to the right select Dynamic Prototypes:

Image 6

This tells the table view that we're going to set up the cells dynamically from our controller.

Next, again in the tree view to the left, select the Table View Cell:

Image 7

And, on the right, set style to Subtitle and Identifier to 'TweetCell' – that's the name we're going to use in our code to find the cell so we can fill out its details:

Image 8

You'll see that the view style changes – that's the style we'll use to display the tweet text as the title, and tweet author as the subtitle:

Image 9

So, now we're all set up in the storyboard part – at least as far as the master view goes. Don't worry – we'll get back to the detail view later on.

Moving on to the controller.

Coding the master view controller

Go into MasterViewController.m by selecting it on the left:

Image 10

This is where all the action will take place. But first we need to set up an instance variable to contain our tweets.

Click on MasterViewController.h to the left:

Image 11

And replace the @interface to @end part with the following code:

@interface MasterViewController : UITableViewController {
    NSArray *tweets;
}

- (void)fetchTweets;

@end

This tells Objective-C that we have a tweets instance variable and a fetchTweets method.

Loading the JSON

Now to the actual tweet fetching. Go back into MasterViewController.m and insert the following method:

- (void)fetchTweets
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSData* data = [NSData dataWithContentsOfURL:
                        [NSURL URLWithString: @"https://api.twitter.com/1/statuses/public_timeline.json"]];

        NSError* error;

        tweets = [NSJSONSerialization JSONObjectWithData:data
                                                 options:kNilOptions
                                                   error:&error];

        dispatch_async(dispatch_get_main_queue(), ^{
            [self.tableView reloadData];
        });
    });
}

What this does is that it makes a separate thread to fetch the JSON data and then goes back to the main thread to update the table view when it's done. The reason to do this is that if we were to get the data using the main thread, then the application would lock up until the data was loaded.

Call this method from inside the viewDidLoad method:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self fetchTweets];
}

This tells the application to load the JSON data as soon as the view loads.

So now our Twitter feed is loaded into to our instance variable named tweets. This now contains an array holding a number of NSDictionary objects where NSDictionary is a key/value collection.

Filling the table view

Next, insert the following two methods:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return tweets.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"TweetCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    NSDictionary *tweet = [tweets objectAtIndex:indexPath.row];
    NSString *text = [tweet objectForKey:@"text"];
    NSString *name = [[tweet objectForKey:@"user"] objectForKey:@"name"];

    cell.textLabel.text = text;
    cell.detailTextLabel.text = [NSString stringWithFormat:@"by %@", name];

    return cell;
}

First run

Try running your application – click the Run icon:

Image 12

And it works:

Image 13

Pretty simple, huh? :-)

Well, can't dwell on our success, so let's go on to something that needs to be done.

The segue

Try selecting a tweet. Our intention was to load the detail view, but this doesn't happen. Why not?

Let's go back into the storyboard:

Image 14

Notice how there's no segue between the master view controller and the detail view controller. What happened was that when we went from static cells to prototype cells in the storyboard before, it erased it, so now it doesn't know what to do. Let's help it out.

Setting up the segue

To the left, CTRL + drag from the Table View Cell to Detail View Controller, and select Push:

Image 15

Now it knows what to do, so try hitting Run again.

Image 16

And it works.

Click on the segue between the table view and detail view:

Image 17

And change its identifier to 'showTweet':

Image 18

That's how we're going to identify it later in the following code.

Responding to the segue

In MasterViewController.m, right below #import "MasterViewController.h", insert the following code:

#import "DetailViewController.h"

This is to give us access to the detail view controller from the master view controller.

Insert the following method:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"showTweet"]) {

        NSInteger row = [[self tableView].indexPathForSelectedRow row];
        NSDictionary *tweet = [tweets objectAtIndex:row];

        DetailViewController *detailController = segue.destinationViewController;
        detailController.detailItem = tweet;
    }
}

Basically what this does is that it tells the app what to do when it hits the segue between the master view and the detail view. It identifies the selected row, finds the tweet, and then sets the detailItem property on the detail view controller. (The detailItem property was automatically created when we selected Master-Detail Application in the beginning. Thanks Xcode!)

Now we're ready to do the detail view controller.

Finishing the detail view

Open up the storyboard and double click on the 'Master' and 'Detail' titles and change them to 'Tweets' and 'Tweet' accordingly:

Image 19

Delete the label saying 'Detail view content goes here'. We'll be creating our own.

Insert a label for the name, a label for the tweet, and an image view for the profile image, like this:

Image 20

You can customize the text sizes like you want.

Creating outlets for the detail view

We'll need a way to call these new controls from our code. This is done by creating three outlets which is a sort of wire, or connection, between the view and the controller. In DetailViewController.h, replace the @interface line with the following code:

@interface DetailViewController : UIViewController {
    IBOutlet UIImageView *profileImage;
    IBOutlet UILabel *nameLabel;
    IBOutlet UILabel *tweetLabel;
}

Now we have created the outlets. We now need to reference, or connect, these from our views. To the left, CTRL + drag from Detail View Controller to 'Label – Name goes here' and select nameLabel:

Image 21

CTRL + drag also from Detail View Controller to 'Label – Tweet goes here' and select tweetLabel, and from Detail View Controller to 'Image View' and select profileImage.

Now we can call the labels and image view from our code.

Loading the detail view

In DetailViewController.m, replace the configureView method with the following code:

- (void)configureView
{
    if (self.detailItem) {
        NSDictionary *tweet = self.detailItem;

        NSString *text = [[tweet objectForKey:@"user"] objectForKey:@"name"];
        NSString *name = [tweet objectForKey:@"text"];

        tweetLabel.lineBreakMode = UILineBreakModeWordWrap;
        tweetLabel.numberOfLines = 0;

        nameLabel.text = text;
        tweetLabel.text = name;

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSString *imageUrl = [[tweet objectForKey:@"user"] objectForKey:@"profile_image_url"];
            NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];

            dispatch_async(dispatch_get_main_queue(), ^{
                profileImage.image = [UIImage imageWithData:data];
            });
        });
    }
}

Final run

Try running the code, and there you have it – a list view and a detail view showing the tweet!

Image 22Image 23

Hope you liked it :-)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Denmark Denmark
Lasse is a long-time programmer, having more than 20 years of programming experience and more than 15 years of experience programming for the world wide web. He writes articles about Ruby on Rails, programming, SEO, and, recently, iOS programming.

Comments and Discussions

 
Questioncreate a rss feed for website apk Pin
Member 1171232022-May-15 11:25
Member 1171232022-May-15 11:25 
GeneralMy vote of 4 Pin
KarstenK4-Nov-14 22:06
mveKarstenK4-Nov-14 22:06 
Questionenable to click the url Pin
alayoup29-Oct-13 13:51
alayoup29-Oct-13 13:51 
QuestionData parameter is nil Pin
zairy123454-Dec-12 20:50
zairy123454-Dec-12 20:50 
AnswerRe: Data parameter is nil Pin
Member 979651429-Jan-13 19:41
Member 979651429-Jan-13 19:41 
GeneralRe: Data parameter is nil Pin
Daniel Sadjadian20-Jun-13 9:31
Daniel Sadjadian20-Jun-13 9:31 
QuestionAPI is out of order Pin
vrutti5-Nov-12 19:13
vrutti5-Nov-12 19:13 
AnswerRe: API is out of order Pin
Seth-B31-Jan-13 10:18
Seth-B31-Jan-13 10:18 
GeneralRe: API is out of order Pin
Member 102569596-Sep-13 4:33
Member 102569596-Sep-13 4:33 
Question"Duplicate declaration of method 'tableView:numberOfRowsInSection:' Pin
Robert A Wilson8-Oct-12 3:32
Robert A Wilson8-Oct-12 3:32 
QuestionButtons Pin
techd845-Sep-12 6:48
techd845-Sep-12 6:48 
QuestionMakeing this a universal app Pin
techd8417-Aug-12 23:59
techd8417-Aug-12 23:59 
Answerjson Pin
trung_vu1-Aug-12 16:36
trung_vu1-Aug-12 16:36 
QuestionApp crashes with another JSON Feed Pin
Member 927109417-Jul-12 23:16
Member 927109417-Jul-12 23:16 
AnswerRe: App crashes with another JSON Feed Pin
phamthanhnhan141-Apr-13 8:28
phamthanhnhan141-Apr-13 8:28 
QuestionMaking a simple Twitter app using iOS 5, Xcode 4.2, and storyboards Pin
chamara2k21-May-12 15:08
chamara2k21-May-12 15:08 
QuestionFriends tweets Pin
Member 89338185-May-12 18:33
Member 89338185-May-12 18:33 
QuestionReTweet function? Pin
DannyBribiesca4-May-12 16:42
DannyBribiesca4-May-12 16:42 
QuestionTimestamp Pin
Stewart Crainie25-Mar-12 3:43
Stewart Crainie25-Mar-12 3:43 
AnswerRe: Timestamp Pin
techd847-Sep-12 12:28
techd847-Sep-12 12:28 
QuestionConversion Array to String? Pin
Member 822280517-Feb-12 11:26
Member 822280517-Feb-12 11:26 
Question.json Pin
Member 822280514-Feb-12 11:29
Member 822280514-Feb-12 11:29 
AnswerRe: .json Pin
lassebunk14-Feb-12 11:44
lassebunk14-Feb-12 11:44 
GeneralRe: .json Pin
Member 822280515-Feb-12 11:26
Member 822280515-Feb-12 11:26 
GeneralRe: .json Pin
lassebunk15-Feb-12 11:28
lassebunk15-Feb-12 11:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.