In this three-part tutorial, we will cover how to create a basic Twitter client that allows the user to display tweets of a particular Twitter account and tweet from that account as well. The main objective is to teach you how to use some common viewcontrollers in Apple iOS and take advantage of a third-party library in your custom application.
My first step when creating an app is always similar to Figure A.
Figure A
Napkin sketch
This tells me I’m looking for an app with a single view and some sort of popup view, which will perform one task, tweet to the Internet on my Twitter account. This is very helpful because it makes it clear to me what the app needs to have in order to function.
Let’s jump right in and create our project by launching XCode and from the File menu (Figure B) selecting New | Project | Single View Application.
Figure B
Choose your template carefully
After clicking Next, you will get a screen similar to Figure C.
Figure C
Project options
Give your project a descriptive name; in this case we called our project TechRepublicTwitter1, or TRTw1 for short. It is important not to include spaces in your project name as this may cause problems later on with file paths. Eventually you will get into the habit of not seeing the spaces when you are in “Code Mode” and will get comfortable simply sticking words together or using the infamous “_” underscore as a space.
Organization Name can be anything you want as well as Company Identifier. The Bundle Identifier is a reverse domain notation used by Apple to identify each app via a Provisioning Profile for each app.
Class prefix is the name you want XCode to append to each Class File you create for this app. You may use the same app name, but keep in mind the only thing this does is prefix any new Class File with “TRTw1” in our case. So for example, when you create a view controller, it would be named TRTw1ViewController instead of just ViewController. Personally I don’t like this because if I later want to move a Class File to a new project, I have to rename the Class File because the prefix has nothing to do with the new project.
Our project will only be designed for the iPhone, so we will leave Devices with iPhone as the only selection. Otherwise we would select iPad or Universal if we wanted to make the app for both.
Finally, we will be using Storyboards and ARC. The former is a feature that helps programmers by allowing them to use a graphical blueprint to create new screen layouts. The latter is also a new feature that allows programmers to forget about memory management. As for Unit Testing, we won’t be looking into that anytime soon as it is quite an advanced topic.
Once we get click “Next”, we are asked to select a folder to save our project to. I recommend you be organized about this, so keep all your XCode projects in a specific location. You should now be at a screen that looks something like Figure D.
Figure D
A new project
The left hand pane is the Project File Navigator and in it you can see the files for your project. When you select the topmost level, the one with the blue icon, you can see your Project and Target Settings in the center window. If you select a class file, then you will see its contents. The right-hand pane displays certain attributes of the selected file in the various Inspectors which we will study as we go along.
As you can see in the Project Navigator, XCode created the following Class Files for you:
- AppDelegate
- ViewController
- MainStoryboard
Other important files to peruse inside Supporting Files are:
- TRTw1-Info.plist
- TRTw1-Prefix.pch
- Main.m
The Info.plist file stores basic app information we will explore later on. The Prefix.pch contains special headers for files that you want to import on an app-wide basis instead of class-wide. Main.m is the file called on application launch, and if you take a look, it basically “runs” the AppDelegate class file.
More interesting files
Now let’s look at more interesting files. As mentioned above, the app loads the main.m file which in turn calls the AppDelegate. Every app has a main.m and an AppDelegate. The AppDelegate has one very important method, the:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
In our app we are using Storyboards, which basically tell the app what view to present first. When Storyboards are not used, it is the AppDelegate that runs the show and you will see its applicationDidFinishLaunchingWithOptions method populated with code to create and present the first viewcontroller.
If you run your app now you will simply get a blank screen. This is the view presented by ViewController, which at the moment contains nothing and has a white background.
Before we dive into the code, let’s revisit our sketch:
Our app will only do one thing, tweet! This means the button in the center will call a method tweet some text. It is important to keep this in mind when coding, therefore, I like to start out by coding just method names with comments in them. As we will see, methods connected to UIControls such as UIButtons, have a return type of IBAction because they are tied to an Interface Builder action. Thus I would start by coding, in comments, what I want my app to do in that method.
So let’s add this to ViewController.m, at the very top:
#import "ViewController.h"
@interface ViewController ()
- (IBAction)tweet:(id)sender;
@end
@implementation ViewController
- (IBAction)tweet:(id)sender {
//App requires internet, check connection
//App requires credentials, check credentials
//Other checks
//Build tweet data
//Perform tweet
}
As a coder it is important to keep code organized and writing in comments of what a method will do, before writing the actual code, will help you organize your code for reusability and readability later on.
What we are doing is declaring an IBAction method called tweet in the interface section. Then we are creating the method in the implementation so we can fill it up with code.
These .h/.m class files are the underpinning code for the actual view controller. And you could design the entire interface programmatically. However, we chose to use Storyboards, which give us a visual way of designing our view controllers. Switch to MainStoryboard and you will be presented with the screen shown in Figure E.
Figure E
MainStoryboard
Now drag a Round Rect Button object from the Object Library on the right hand pane and drop it onto our ViewController. Double click it and change the label text to Tweet. Finally, let’s add some eye candy – do a Google search for a nice Twitter bird image and save it to your computer.
This is important, so learn to do it properly. Select the folder you want to put your images in from the left hand pane. Now right click and select Add Files. (Figure F)
Figure F
Add files
Now browse for the image file on your computer and select it. You will be presented with a screen like the one shown in Figure G.
Figure G
Add an image
Choose your image and make sure to check Copy items into destination group’s folder (if needed). Now click Add and you are done. The image file appears in the folder you selected originally.
What you did was import an asset, not only as a reference to the project, but when you checked the Copy items checkbox, you also copied that file into your project. Now it doesn’t matter if you erase the original downloaded file where you had it stored because your project has a copy in its Project Folder.
Now in the right hand pane click on the filmstrip icon to switch over to the Media Library which contains your only imported asset so far. Drag it onto the viewcontroller to get a nice looking scene. (Figure H)
Figure H
Twitter bird
Now let’s hook up the button so it actually does something. Select the entire viewcontroller so that your screen looks like Figure I.
Figure I
Select the entire viewcontroler
Notice how you get a lot of Connection Outlets on the right hand pane. The icon selected on top is a circle with a right arrow. This is the Connections Inspector which displays all the connections your selected object can make. So let’s connect the Tweet Received Action to the Tweet button by clicking on the empty circle and dragging it to the Tweet button. From the popup list select Touch Up Inside and the connection is created.
You now have a fully functioning app. The only thing is that the button calls a method, which is currently empty. However, before we can fill up that method, we need to import the Twitter Framework. It’s a little dry, but quick, so let’s get it out of the way.
On the left hand pane, select the blue Project Icon and from the main window select the Target. Now from the Build Phases tab expand Link Binary with Libraries and click the “+” button. In the search field type Twitter and the Twitter Framework will appear. (Figure J)
Figure J
Twitter Framework
Select it and click the Add button. BOOM! Just like that, your app can now access Twitter.
Let’s import this new framework into our app by adding this line atop ViewController.m:
#import <Twitter/Twitter.h>
Now inside our tweet method add this:
//1. Checks for required resources
if ([TWTweetComposeViewController canSendTweet]) {
NSLog(@"Connected and Authorized");
} else {
// If required resources are not available
NSString *message = @"Please check your internet connection or Settings for a configured Twitter Account";
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"We're sorry" message:message delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
[alertView show];
}
Let’s see what we did.
First, we call a method to check if we can tweet and if we can’t, we pop an alert to let the user know about the problem. This is the main structure of our tweet method. The method itself, canSendTweet, is a Class Method which checks for Internet connectivity and account credentials. If they exist, it returns true.
This means that we will not waste processor time and power going through a bunch of code that in the end will be for not if we don’t have the required resources. So any code for preparing the actual tweet will go in this fork of the If-Statement. If it returns False, it means we cannot tweet, so we won’t do anything except prepare a UIAlert to pop up for the user to read.
So let’s look at what we have to do in order to create a tweet if we are allowed to do so. First and foremost, the tweet’s text:
//2.
// Init TweetComposeViewController
TWTweetComposeViewController *vc = [[TWTweetComposeViewController alloc] init];
// Set tweet text
[vc setInitialText:@"My first programmer tweet!"];
Here we instantiate a TWTweetComposeViewController object and set its text to our desired tweet. An important distinction here is that the first method we called, canSendTweet, was a Class Method because it was called on the class itself. There was no instance required for it to be called. Now we are actually creating an instance of it, vc, in order to call Instance Methods on it, such as setInitialText.
Just for fun, place your cursor over the TWTweetComposeViewController name and right click on it and Jump to Definition. This takes you to the Class file where those methods are defined. You can see the “+” in front of the canSendTweet method versus the “-” in front of the setInitialText method name.
Now let’s add a picture to tweet. We are going to hardcode the image name for now. My image happens to be called images-27.jpeg. So let’s add this code where we left off:
//3.
// Hardcode an image
UIImage *image = [UIImage imageNamed:@"images-27.jpeg"];
[vc addImage:image];
As you can see, we take an instance vc and add an image to it.
Another popular feature of tweets is attaching URL’s to them. We can do this by adding the code:
//4.
// Hardcode a URL
NSURL *url = [NSURL URLWithString:@"http://www.santiapps.com"];
[vc addURL:url];
Again we are simply adding the url to the vc instance. This final step may be a little confusing because of the order but it has to do with a very popular coding concept called blocks.
Normally you call a method on an object and send it variables or some data. Your object takes that data and performs its duties and returns some other data. Blocks is a feature whereby you pass the object some particular code instead of data. This is handy for telling object what to do with a particular load of data. Let’s look at the code and see why it’s helpful:
//5.
// Optional
[vc setCompletionHandler:^(TWTweetComposeViewControllerResult result) {
[self dismissModalViewControllerAnimated:YES];
}];
//6.
// Present TweetComposeViewController
[self presentViewController:vc animated:YES completion:nil];
Let’s think about what SHOULD happen now. You have pieced together your “Tweet Object” and are ready to present it to the user. You should call Step 6; Present the TweetComposeViewController for the user to tap Send or something like that.
What we do is set a property of the vc instance called the Completion Handler which takes a block of code instead of a variable. We are telling our vc instance to execute this code inside the {}.
Finally we present the actual viewcontroller for the user to see the text, image and url we attached to our vc instance. Once the user hits the Send button on that vc viewcontroller instance, the completion handler is called and the [self dismissModalViewControllerAnimated:YES]; is executed, thereby dismissing that very same viewcontroller. (Figure K)
Figure K
Completion handler
The completion handler is handy because it waits for the result before calling the dismissal code. Otherwise your vc could be dismissed prematurely.
I hope you enjoyed Part I of this tutorial and we look forward to seeing you in Part II where we explore how to add your Twitter timeline to this app.