Monday, April 25, 2011

Objective-C Programming in XCode 4 – iPhone iOS 4.3 Hello, World ! tutorial


DemoViewController

1. Install Xcode and create a new project

To develop apps for the iPhone/iPad running iOS, you’ll need a Mac running Mac OS X 10.6.
Apple’s development tools are called Xcode. This tutorial is for Xcode 4, released in March 2011. Please note that you’ll find lots of information on the internet which is valid only for version 3 or 4 of Xcode.
To run your apps on hardware devices, you need to be member in the iOS Developer Program (99$/year). If you are member in the developer program, you can download Xcode 4 for free. If you’re not a member, you can still buy Xcode 4 for $4.99 in the Mac App Store and run your apps in the simulator on the Mac.
So, first step is to download and install Xcode 4 and to run it from /Developer/Applications/Xcode:
Xcode


Choose to create a new project.
Choose iOS > Application > Window-based Application. This is the most simple template for iOS apps. In this tutorial, I intend to show what’s going on and explain all the moving parts in the background. So while there are more suitable templates to build actual apps, please follow along using the bare-boned Window-based Application template.
In this tutorial, I’m going to develop a shopping list app, so if you want to follow along, name your project ‘ShoppingList’. Company Identifier should be a domain name written the other way round. I’m going to use com.example, feel free to use your own domain name. Choose iPhone for Device Family (for the moment, this will be an iPhone-only app) and uncheck Use Core Data (a database framework, we don’t need this right now) and uncheck Include Unit Tests (we will do unit tests only in a later chapter):
Creating a new iPhone project
We now have a new iPhone project.

2. Run the app

Simulator

Check that the iPhone simulator is checked for Scheme and hit Run (⌘R):
Running in the simulator
The empty app should be running in the simulator now:
iPhone Simulator

Device

To run the app on the device, you need to be iOS Developer Program member.
Connect the iPhone to your Mac. Open the Organizer in Xcode via Window > Organizer and choose the device. The first time you might have to enable it for development.
Click the Add to Portal button. It will query for your Apple account password and offer to request a certificate for you. If it asks to wait for your Provisioning Profile to be created, refresh the Provisioning Profiles section until a valid "Team Provisioning Profile: *" pops up there. The icon besides the device should be green by now:
Xcode Organizer
Add to Portal does many things automatically:
  • It creates a developer certificate for you. This includes a public/private keypair which is added to your OS X keychain. iPhone apps need to signed to run on the device and your key will be used to sign your app.
  • It uploads a request to sign the certificate to the Apple iOS Provisioning Portal. Your certificate needs to be signed by Apple, otherwise the app will not run on the device.
  • It adds the Unique Device ID (UDID) of your device to the iOS Provisioning Portal.
  • It creates an App ID in the iOS Provisioning Portal.
  • It creates a Provisioning Profile in the iOS Provisioning Portal. This is the permission to run apps (having a matching App ID) signed with your key on only the devices with the specified UDIDs.
  • It downloads the provisioning profile from the iOS Provisioning Portal and installs it to Xcode and on your phone (you can check that on the phone using Prefs > General > Profiles).
Provisioning Profile
You can now pick the hardware device in the Scheme selector and run the app on the hardware device:
Running in the simulator






App running on the device

3. Use the documentation

Let’s have a look at how the startup of an iPhone app works. The entry point is the main.m file in your project:
main.m
This does some basic setup:
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
Important here is the UIApplicationMain call which initializes the app. To learn more about UIApplicationMain (or about anything), have a look at the documentation. Go to Xcode > Preferences > Documentation and click GET for the iOS Library. This will download all the available documentation:
Download iOS Library Documentation
After it finishes downloading, select UIApplicationMain in the source code file and click Help > Search Documentation for Selected Text:
UIApplicationMain documentation
Hint: Configure a convenient key binding for Help > Search Documentation for Selected Text in Xcode > Preferences > Key Bindings:
Hotkey for documentation

4. Add a UINavigationController

After we have learned how to use the Xcode documentation in part 3 of the iPhone tutorial, let’s add a navigation controller that provides the typical navigation bar that will host the navigation controls like the back button:
Navigation Controller
But before that, some more basics. We have seen the call to UIApplicationMain() in main.m:
int retVal = UIApplicationMain(argc, argv, nil, nil);
From the documentation one can learn that there is an application delegate object which takes control as soon as the application is started. UIApplicationMain loads this object from the application's main nib file by default. Let’s have a look at how this works.
NIB files are created by the graphical user interface editor of Xcode. They have the file extension .xib:
MainWindow.xib
NIB/XIB files contain "pickled" objects. Our .xib file contains two objects, an App Delegate and a Window:
Inspect MainWindow.xib
When the app starts, the .xib file is loaded by UIApplicationMain and all the objects come to life. Let’s have a look at the App Delegate. If you inspect this object, you can see that this object is created from one of our project classes:
How the app delegate is loaded
If you have a look the ShoppingListAppDelegate.m implementation, you’ll see that this class makes the window visible:
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self.window makeKeyAndVisible];
return YES;
}
This is the Window object which is loaded from our .xib file. We will have a deeper look in the connection between classes and objects from .xib files in a later part of the tutorial after we went through some basics of the Objective C language.
So now we know: Our application delegate is loaded from our .xib file and makes the Window from the .xib file visible. Let’s play around with the window a bit. For example, change the background color:
Change the window background color in the NIB
If you run the app now, you will see the Window with the changed background color.
You can add UI objects by dragging them from the Object Library:
Adding a control in interface builder
Let’s see if we can add a UINavigationController the same way. If you try it, you will learn that you cannot drag the navigation controller on the Window. This is because a navigation controller is not a view itself, so it cannot be added to a Window. A Controller contains and manages a View, but it is not a view itself. But we can add it besides the Window as separate object:
Adding a UINavigationController in interface builder
The important point here is: where is the connection between the Window that will be on the screen and the Navigation Controller? Currently there is none, we just added another object which will not be used. We have to establish a connection by telling our Window object that it should use our navigation controller. This is done by setting the property rootViewController on the Window object:
Set the NavigationController as rootViewController for the Window
If you run the app now, you’ll see that the view controller is used by the Window:
Window with NavigationController

5. Add a UIViewController

After we have added a navigation controller in part 4 of the iPhone tutorial, we can now begin to add Views to the app. Views are the screens of the app. A View is usually accompanied by a ViewController which is responsible to manage the View and all the action that is supposed to go on, like reacting on user events.
The UINavigationController that we added in the last part is responsible for managing all the ViewControllers of our app. Because of this, we shouldn’t add anything to the Window directly. Everything we want to show goes into the UINavigationController. So, whenever we want to add a new screen to the app, we add a UIViewController to the UINavigationController. The root view controller (the one which is displayed initially) and its View can be added conveniently in Interface Builder:
Add a view controller
Also add a Slider, Label and Rounded Rect Button to the View and set a title for the ViewController so we have some controls to experiment with later on:
Add View Controls
So by now, if you run the app, you should see the controls you just added inside the View which is managed by the ViewController which is managed by the UINavigationController:
App with some controls
Now, let’s add a some behaviour to our new view. This is the point where we need to start to work with the programming language Objective C.
In this tutorial, I’ll take a chance to try to explain everything to the point where somebody who never did any programming before has a chance to follow. If you already know other programming languages, skip the (for non-programmers) sections and read the (for programmers) sections instead (and vice-versa).

A brief introduction to Objective C Objects (for non-programmers)

We have already seen ‘Objects’ and created them using Interface Builder. Things like Buttons, Labels, Windows, View Controllers, all these are objects. When we drag two Buttons into Interface Builder and run the app, we see two Button objects in action. You can work with objects using two ways. They can have attributes (also called properties) that can be changed. We can do this in Interface Builder or later in our program when the app is running. Have a look at the properties of the Label object in Interface Builder to get an idea what properties you can manipulate:
Label attributes
The other thing we can do with objects is to talk to them by sending them messages. For example, in a later part of the tutorial, we will go to our UINavigationController object and ask it to show some other view.
So, objects have attributes which we can manipulate and we can talk to them by sending messages. Now, you might wonder, where does the definition come from what attributes we can manipulate and what messages we can send? Here is the trick: Every object has some kind of a blueprint which defines these things. This is called a class. A class like UIButton defines attributes and messages. When you create a button, your button object is created using this UIButton blueprint. Now, many classes like UIButton or UIViewController were written by the Apple engineers and we have just to use them like we already did. But sometimes we have to create new classes ourselves. And here is another neat trick: We can not only create completely new classes, we also can take an existing class and add our own parts on top (this is called to create a subclass).
This is what we will do right now. We have this UIViewController object in our app which is responsible to handle all the action in our View. The class UIViewController has lots of attributes we can change and messages we can send. But UIViewController objects also get messages sent to it and we can add extra behaviour by creating our own variant of the class and reacting on such messages.

A brief introduction to Objective C Objects (for programmers)

Objective C has a very dynamic object model, you can for example call methods reflectively or add methods dynamically at runtime. Because of this, I’ll use the term “to send a message” instead of “to call a method”. We will see all the details, like the syntax for defining classes and sending messages, in later parts of the tutorial. In the meantime, check out the The Objective-C Programming Language.

Adding behaviour to a View Controller by creating a UIViewController subclass

Now, let’s say we want our ViewController to do something. Currently nothing happens at all, it is just there, managing our View with the Slider, Button and Label in it. We have this UIViewController object in our .xib and if you look closely, you can see that it is created from the class UIViewController:
Classes in Interface Builder
Lets create a UIViewController subclass so that we can add our own behavior. To do this, right-click the ShoppingList folder and create a new File:
Create a new file
Choose UIViewController subclass:
Create a UIViewController subclass
Choose to create a subclass of UIViewController and uncheck With XIB for user interface (we want to connect it to our existing XIB instead of creating another XIB file):
Create a UIViewController subclass
Name it anything you want, for example DemoViewController.m:
UIViewController file name
We now have two new files in our project: DemoViewController.h and DemoViewController.m. We will have a look at all the code in these files in great detail in a later part of the tutorial.
For now, let’s just writing some text out to the console when the view is loaded so we can see something happening. Scroll down in the DemoViewController.m file looking for viewDidLoad. viewDidLoad is a message which is sent to objects of our class whenever the view just came to life:
Add a NSLog(@"DemoViewController says hello"); statement to log a message to the console:
DemoViewController
Now, one last step is necessary for this to work. We need to change our XIB so that it doesn’t create a regular UIViewController object but a DemoViewController:
Change View Controller class in XIB
Now run the app and check the console for the message:
Console message

No comments:

Post a Comment