Friday, April 10, 2009

Tutorial: Analysing XCode's "Utility Application" iPhone-template in Interface Builder

In the last two posts we analysed XCode's "Window-Based Application" template, with an emphasis on understanding how to use Interface Builder (IB) during iPhone application development. That template is a good starting point, since it's very simply but yet makes rather good use of IB.


Now, we'll move onto something more exciting by analysing XCode's "Utility Application" template, so start up XCode, choose  "File/New Project" from the menu and select the Utility Application project and name it Util1. This is a quite interesting project, since it has multiple classes, multiple xib-files and even some user interaction via a GUI button. Lets start by looking at the file structure in XCode:


Util1

  Main View

    MainView.[hm]

    MainViewController.[hm]

  Flipside View

    FlipsideView.[hm]

    FlipsideViewController.[hm]

  Application Controllers

    RootViewController.[hm]

    Util1AppDelegate.[hm]

  Resources

    FlipSideView.xib

    MainView.xib

    MainWindow.xib

    Info.plist


Ok, it seems as if there are six classes (MainView, MainViewController, FlipsideView, FlipsideViewController, RootViewController and Util1AppDelegate). and three xib-files (FlipsideView, MainView and MainWindow). The things we recongnize from before are Util1AppDelegate, MainWindow.xib and Info.plist.


Before we dive into the details, build and run the project by pressing CMD-Return to see what it does! A grey background with a small icon in the lower right corner should appear. The small icon has a lowercase "i" in it, which in iPhone language means that it is an "info-button". Press it and see what happens!


Wow, it triggered a really nice graphical effect which "flipped" the grey screen away and flipped in a black screen with some kind of title bar containing the text "Util1" and a "Done"-button at the top of the screen. Let's press the "Done-button" and see what happens.


Cool, it flipped back to the original grey screen again! Ok, as you can see, this is a very nice application which probably would make anyone you showed it to drool in envy and bow in respect to you if you said that it was you who have made it!


After watching this fantastic presentation we understand why some of the files have names with the word "Flipside" in them - they probably have something to do with the stuff that was "flipped in" when we pressed the info-button on the main screen. Hey, there is a main screen also? Ok, now we understand why some files have the word "Main" in their names!  This flipping effect is actually designed to make it look like you can look at the backside of your main screen - almost like flipping your iPhone around in order to admire the beautiful Apple-logo ;)


Ok, enough talk, let's start wading through the files.


Examining the source files


Resources/Info.plist


Double-click it and you'll see that "Main nib file base name" is set to MainWindow, which means that Resources/MainWindow.xib will be loaded automatically when starting the application.


Before we start analysing the xib-file, we'll take a look at the classes, because otherwise it might be a bit hard understanding the objects and connectionsin the xib-file.


Application Controllers/Util1AppDelegate.h


@interface Util1AppDelegate : NSObject <UIApplicationDelegate> {


Ok, this is the object implementing the UIApplicationDelegate protocol...


    UIWindow *window;


and it has a window...


    RootViewController *rootViewController;


and something called a RootViewController. If you look in the file list in XCode, you'll see that this is one of the classes in our project so we'll dive into that one soon.


@property (nonatomic, retain) IBOutlet UIWindow *window;


We want to manipulate our GUI objects from IB so we declare accessor methods for 'window' and also tag it with IBOutlet so that IB will discover it.


@property (nonatomic, retain) IBOutlet RootViewController *rootViewController;


The same goes for the mystical 'rootViewController'.


Application Controllers/Util1AppDelegate.m


- (void)applicationDidFinishLaunching:(UIApplication *)application {


We want to do something when the application has finished launching so we implement the appropriate method from the UIApplicationDelegate protocol.

    

    [window addSubview:[rootViewController view]];


The mystical rootViewController has a reference to a UIView object, accessible by calling it's 'view' method. We want to add this view to our window in order to display it, which is accomplished by calling 'addSubView' on our UIWindow 'window'


    [window makeKeyAndVisible];


Calling makeKeyAndVisible on a UIWindow makes it visible as well as making it the "first responder" of events (touches).


Application Controllers/RootViewController.h


@interface RootViewController : UIViewController {


The mystical class RootViewController turns out to be a subclass of UIViewController. A UIViewController is primarly used if you have a full screen view, which we do, and using it instead of just a view has a couple of benefits, but we won't go into that now.


    UIButton *infoButton;

    MainViewController *mainViewController;

    FlipsideViewController *flipsideViewController;

    UINavigationBar *flipsideNavigationBar;


We have an UIButton called 'infoButton', two other view controllers and a navigation bar. Judging by their names the view controllers are used for the main screen and the flipside screen we saw when we tested the application.


}


@property (nonatomic, retain) IBOutlet UIButton *infoButton;

@property (nonatomic, retain) MainViewController *mainViewController;

@property (nonatomic, retain) UINavigationBar *flipsideNavigationBar;

@property (nonatomic, retain) FlipsideViewController *flipsideViewController;


We want all of our properties to be accessible by other classes so we declare them as properties, but we only mark 'infoButton' with IBOutlet so apparently that's the only thing we will manipulate from IB.


- (IBAction)toggleView;


IBAction instead of IBOutlet - that's something new! You'll have to read the full post before understanding this one, so for now you can ignore it.


Main View/MainViewController.h

Flipside View/FlipsideViewController.h


Both these just declare that they are subclasses of UIViewController.


MainView/MainView.h

FlipsideView/FlipsideView.h


Both these just declare that they are subclasses of UIView.


MainView/MainView.m

FlipsideView/FlipsideView.m


Both these are quite unexciting, but the following might be worth explaining


- (id)initWithFrame:(CGRect)frame {


Initialising this view is done by passing it a CGRect which defines a rectangle called 'frame', which will be used to set the size of the view. The return type is 'id' since we will return an object - a MainView or FlipsideView object to be precise.


    if (self = [super initWithFrame:frame]) {


The CGRect 'frame' is immediately passed to it's superclass UIView to take advantage of the initialisation it already provides. If the UIView initialisation worked we'll get a non-null pointer to an UIView in 'self' - that's "us".


    return self;


Here we return a pointer to "ourselves" so our caller can use the object we now have successfully initialised.


Main View/MainViewController.m


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {


Creating a MainViewController object will apparently be done by providing a nib (IB-file).


    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {


This nib is directly passed on to our superclass UIViewController to let that handle the initialisation.


Flipside View/FlipSideViewController.m


This class has no "init"-method like MainViewController. Instead it has a method called viewDidLoad. This method is implemented in UIViewController (our superclass) and we should override it, as we do here, if we want to change something after our view has been loaded from a nib.


Since we implement this method, it means that this view will be loaded from a nib from somewhere else in our application. 


- (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];      

}


We apparently want to change the background colour after loading, but to make everything work as intended we also call the 'viewDidLoad' method of our superclass to take advantage of the functionality it provides.


Examining of the xib-files


Finally, we have looked at the basic funcionality of all the classes in our project. Let's move on to the xib-files!


Resources/MainWindow.xib


File's owner


CMD-4 reveals that the object which is going to use ("own") this file is of the class "UIApplication", just like we've seen before. As we know by now, UIApplication objects has a delegate object which implements the UIApplicationDelegate protocol. Specifying the delegate object can be done fron IB by setting the 'delegate' outlet of an UIApplication object. CMD-2 reveals that this object's delegate outlet is set to "Util1 App Delegate".


Util1 App Delegate


CMD-4 shows that the class of this object is "Util1AppDelegate". It also shows that this class has two outlets; 'rootViewController' which is of type "RootViewController" (one of the classes we defined ourselves in the project) and 'window' of class UIWindow. CMD-2 shows that 'rootViewController' is connected to "Root View Controller" and 'window' is connected to "Window".


Root View Controller


CMD-4 gives us that this object is of the class "RootViewController" (one of our classes). and that it has an outlet called 'infoButton' of type UIButton. It also shows us something we haven't seen before - an "action" called 'toggleView' of type id. If you have forgotten where this come from, take a look at "Application Controllers/RootViewController.h" in XCode by pressing the small right-arrow icon in the title bar above the 'toggleView' row in the "Class actions" box in the Identity Inspector (CMD-4).


This is getting exciting, so let's have a look at the connections right away! Press CMD-2 and you'll see that 'infoButton' is connected to something called "Light Info Button" and 'toggleView' is connected to "Light Info Button Touch Up Inside". You might have noticed that this object apparently also has an outlet called 'view' which is connected to something called "View". These are here because "RootViewController" is a subclass of "UIViewController" and that's where the 'view' outlet comes from. In fact, UIViewController has two other outlets as well; 'navigationItem' and 'tabBarItem'. Take yet another look at the "Root View Controller" connections (CMD-2) and you'll find those two there as well, but not connected to anything.


By the way, if you want to verify that these outlets really come from UIViewController, bring up the Library (CMD-L) and drop a "View Controller" in the MainWindow.xib window. Select it and press CMD-4 and you'll see all the outlets mentioned above . When you're done verifying, select the "View Controller" icon and press backspace to get rid of it.


A short note on the section "Referencing outlets". Select "Util1 App Delegate" and press CMD-4. In the "Referencing outlet" section you'll see a "connection" that looks like this: 'delegate' -- 'File's owner". What this means is that the outlet 'delegate' in the object 'File's owner' points to this object. If you read it from right to left it becomes even clearer: "File's owner".delegate = "this object".


Ok, lets leave the generic UIViewController and return to our view controller. As mentioned above the 'view' outlet is connected to an object called "View", but how come we see no icon for it in the xib-file contents window ("MainWindow.xib"). That's because you can embed objects in other objects in IB and that is exactly what the author of this xib-file has done.


To reveal these embedded objects, we have to change the view mode of the contents window, which you do by pressing one of the small icons in the upper left part of the window - just above the text "View mode". Press the middle one and you'll be presented with a hierarchical navigation view mode (tree mode). Click the arrow to the left of "Root View Controller" and the mystical "View" object should appear. Press the arrow to the left of that one and the even more mystical object called "Light Info Button" should appear. If you are really really observant you could also find these - or at least the info button - by double clicking the "Root View Controller" icon in the "normal" view mode of the contents window. (Hint: it's in the lower right corner of the window that appears if you try it...)


By they way, if you wonder about how to embed an object into another object you do that by dragging the object you want to embed onto the other object. That's how View was put into "Root View Controller". For buttons and elements where the position is important, you can also position them at the same time as you embed them. Try that by double-clicking "View" in the tree view. This should bring up a "blank window". The info button already present is barely visible in the lower right corner. Bring up the Library (CMD-L) and drag a "Segmented Control" from the "Inputs & Values" section into the blank view. It should immediately appear and you can position it and size it at will. Check the tree view of the contents window to confirm that it appeared under View in the tree. Remove it by selecting it and pressing backspace, when you're done playing.


View


When you are in the "tree mode" it becomes easy to select the View icon so do that and press CMD-4 and then CMD-2. Nothing exciting, it's a simple UIView object with no outlets and no connections.


Light Info Button


In tree mode it's just as easy to select the "Light Info Button" icon and press CMD-4. Hey, not even this was that exciting - it's just a simple "UIButton"! Ok, maybe CMD-2 will make things a bit more fun? Wow, look at the list of... "stuff" that appears! If you look closer you'll see that the "stuff" actually are called "Events" and apparently we have done something with one of them - "Touch Up Inside". It looks like this event is "connected" to "Root View Controller toggleView". Sounds familiar? It should, because we mentioned it above. We earlier saw that we defined an IBAction called 'toggleView' in RootViewController.h, something which you can also see by selecting the "Root View Controller" icon here in IB and pressing CMD-2. Cool! It thus seems as if "events" are connected to "actions". Sounds reasonable!


Let's dig deeper into this. If you bring up XCode and do a project-search for 'toggleView' by pressing CMD-F you'll see that it is defined in RootViewController.h simply as -(IBAction)toggleView and then it is implemented as a method in RootViewController.h using the same "signature". Could it be that this method gets called when the info button is pressed. Yes, that's right! Or actually it gets called when the "Touch Up Inside" event is generated by the button, which means that you have to touch the button ("touch down") and remove your finger ("touch up") while the finger is still "inside" (hoovering over) the button.


One mystery remains for the infoButton. How did the iPhone know that we wanted a button which looked liked a the letter "i" inside a ring? Press CMD-1 to find out. Here you'll see that the type is specified as "Info Light" and that explains that mystery!


Window


Double click the Window icon and a black window appears. CMD-4 reveals that it is a plain UIWindow and CMD-1 confirms that the background colour is set to black.


Resources/MainView.xib


File's owner


CMD-4 shows us something new. The "File's owner" objects we have worked with so far have all been UIApplications, but this one is of the class "MainViewController", which is one of our own classes. We see that it has no outlets of its own, but if we switch to the connections tab (CMD-1) we see that the three outlets inherited from its superclass UIViewController are there; 'navigationItem', 'tabBarItem' and 'view'. The 'view' outlet of the superclass is connected to something called "Main View" and if you take a look at the xib-file contents window (MainView.xib), you'll see where "Main View" came from - yes there is an object in this xib called just that.


Main View


CMD-4 says this object is of class "MainView" and that it has no outlets of its own. CMD-2 shows that there are no inherited outlets as well. However, we see that there exists a connection via a "Referencing outlet". Using the syntax from above, this means that "File's owner".view = "this object". In our case "File's owner" is of the class "MainViewController", which in its turn is of the class "UIViewController", which in its turn has an outlet called 'view and that's the outlet that this object is connected to.


Resources/FlipsideView.xib


File's owner


CMD-4 shows that the class of the object is "FlipsideViewController" and that it has no outlets of its own. CMD-2 shows that the standard UIViewController outlets are there and that one of them, 'view', is connected to "Flipside View"


Flipside View


CMD-4 gives us a class of "FlipsideView" and no outlets. CMD-2 shows a "referencing outlet" meaning that "File's owner".view = "this object".



Summary


Wow, what a ride! We have learned a lot this time, but even after digging through so much one mystery remains and that is how the "title bar" and "Done"-button on the "flipside" was created since we saw no trace of them in Interface Builder, not even after learning about the "tree view" of the xib-file contents window. Well, that's beacuase those GUI elements were created programmatically, that is by writing Objective-C source code, but we won't analyse that here since we're now trying to focus on the IB. If you're curious about how that works I suggest you go back to XCode and do a project search (CMD-F and remember to enable "ignore case") for "navigation". Hmm, that sounded like an excercise for the reader to me ;) Good luck!


Tutorial: Creating an iPhone xib-file from scratch in Interface Builder (IB)

In the last post we analysed the contents of MainWindow.xib in order to try to understand how Interface Builder (IB) works and what you can use it for. This time we will try to create an IB-file from scratch in IB, since syntehsizing (creating) something often is the best way to confirm that you really understood everything you learned while analysing a subject.

Start IB, choose File/New from the meu and select the "Empty" template. This creates a xib called "Untitled" which contains "File's owner" and "First responder".

Select "File's owner" and press CMD-4 and you'll see that it is of the class NSObject. The owner of the xib-file we are currently creating is an object of type UIApplication, so we should start by changing the class to that. To do that, press CMD-4 and choose UIApplication from the drop-down list.

As soon as you do this an outlet called 'delegate' is automatically added in the "Class outlets" section. This is because an UIApplication normally is connected to an object which implements the UIApplicationDelegate protocol and that's where the 'delegate' name comes from.

The next natural step therefore is to create an object which implements that protocol. We have aldready defined such a class in XCode called "Test1AppDelegate" (see last post), so we'll create an object of that class.

Choose "Tools/Library" from the menu or press CMD-L. Select "Cocoa Touch Plugin/Controllers/Object" and drag the object icon into the "Untitled" window. This creates an object simply called "Object" in our IB-file.

CMD-4 reveals that this newly added object is of class NSObject, but we want it to be of class "Test1AppDelegate". Since this is a non-standard class that exists only in our project, we need to import the class definition/specification so that IB understands how to use it. To do this, choose "File/Read Class File" from the menu and navigate to Classes/Test1AppDelegate.h and select it.

Select "Object" again from the file contents window ("Untitled")  and press CMD-4. Now you should be able to select "Test1AppDelegate" as the class for this object. You should also see that this class has one outlet of type UIWindow with the name'window', which should be familiar since that is our window.

Let's connect the 'window' outlet to an UIWindow! To do this, we first have to create an UIWindow object, so press CMD-L to bring up the Library window. Choose "Windows, Views and Bars" and drag the Window-icon into the file contents window ("Untitled"), that is, drop it right beside the "Test1 App Delegate" object we just created.

To connect the 'window' outlet of "Test1 App Delegate" to the UIWindow object we just created, position the mouse over the "Test1 App Delegate" icon and press and hold the CTRL-key. Keep on holding the CTRL-key and press and hold the mouse button while moving the mouse pointer towards the Window icon. A blue line should appear, going from the the icon to the current position of the mouse pointer. Release the mouse button when the pointer is positioned over the Window icon.

Now a small pop-up window called "Outlets" should appear. Select the 'window' outlet, which should connect the Window object to the 'window' outlet of "Test1 App Delegate". To verify this, select "Test1 App Delegate" and press CMD-2. The 'window' outlet should have the value "Window", which is the IB-name of the UIWindow object we created a minute ago.

Now we should make "Test1 App Delegate" the delegate of our UIApplication, which is called "File's owner" here. Repeat the CTRL-drag procedure from above, but this time drag from "File's owner" to "Test1 App Delegate" and select the 'delegate' outlet. Done!

This procedure of CTRL-dragging between icons to connect an object to an outlet is in my view a bit counter-intuitive since I think the direction you have to drag the mouse is "wrong". To connect one of object A's outlet to object B, you should CTRL-drag from A to B. For me, it would have been more intuitive to instead CTRL-drag from B to A, if I wanted to connect B to A, but I guess that's just a matter of perspective.

To help us verify that we have actually succeeded in re-creating a "copy" of the MainWindow.xib file that was automatically created for us by XCode, click the Window icon and press CMD-1. Locate the box where you can set the window's background colour and set it to green or some other colour than the default white. As a final step, save the xib as "MyMainWindow" in the "Test1AppDelegate" project. IB will ask if you want to add it to your project which is exactly what we want so answer yes.

Go back to XCode and drag the MyWainWindow.xib file to the resources folder and then click on Resources/Info.plist to change MainWindow to MyMainWindow. This instructs iPhone to use our re-created xib-file instead of the one that XCode created for us.

Build and run the project by pressing CMD-Return and you should be presented with a green screen instead of a white one. Wow, we managed to quite easily create our own xib-file from scratch and "integrate" it in the application we created in XCode!


Sunday, April 5, 2009

Tutorial: Understanding the iPhone Interface Builder (IB)

In november 2008, I decided to start exploring the Apple iPhone development environment. The main reason for doing that was that I wanted to port a mobile game I wrote for the Mophun platform five years ago. Another reason was that I thought the iPhone seemed like an exciting platform.

Before starting to code I took the time to read quite a lot of official documentation from Apple. The primary problem with the Apple iPhone documentation in my view is that there is so much of it that it becomes hard to choose what to read. A secondary, but quite important, problem is that a lot of the documentation contains the wrong information, at least for someone who isn't familiar with Mac development. That the documents contain a lot of words, but little information is also quite frustrating. Thankfully, the API documentation available in XCode is much better.

However, I managed to find a handful of good documents and after reading them I thought I was well prepared for iPhone development. At this time there was almost no tutorials, blogs or discussion forums on the Internet since the Apple NDA had just been lifted. Therefore I started to explore on my own and got a complete chock when I started up the Interface Builder (IB). I didn't understand anything, which made me feel like a complete fool. Especially after spending so much time reading documents.

I quickly gave up the IB and started doing things programmatically instead, that is, doing everything by hand in source code; creating windows, views, buttons, etc. This turned out to be really simple so my self confidence was (partly) restored. It also made me feel that the problem wasn't my lack of understanding, but the lack of good documentation for the IB - see what a little self confidence can do ;)

A few days ago, I decided to return to IB and make a new attempt at understanding it. This time it went a little better since I had gained a lot of real iPhone experience since the last attempt. To force myself to really understand it, I decided to start by trying to fully explain the code and xib-files created by the XCode project templates.

Create the project.
  • Start XCode or choose "File/New project" from the menu-bar if XCode already is running.
  • In the left column, select: "iPhone OS/Application".
  • In the right box, select: "Window-Based application".
  • In the right bottom of the window, click the "Choose"-button.
  • Rename the project to "Test1" (that's the figure one, not the letter ell) by replacing the text "Untitled" in the "Save as"-box and save the project an appropriate place and press the "Save"-button.
After completing these steps, XCode will create a set of files for you which are displayed in the left column of the window using an expandable tree-view. Below is the hierarchy of files we will concentrate on in this post:

Test 1
  Classes
    Test1AppDelegate.h
    Test1AppDelegate.m
  Resources
    MainWindow.xib
    Info.plist

Explanation of the files

Classes/Test1AppDelegate.h

This is the h-file (specification) for the class in our application which will handle events/messages from the UIApplication-object which exist in all iPhone applications. Let's look at the most import lines of code.

Test1AppDelegate : NSObject <UIApplicationDelegate> {
Specifies that this object inherits from NSObject and implements the UIApplicationDelegate protocol. (A protocol is similar to an interface in Java.)

UIWindow *window;
The object will make use of an UIWindow which is the "base GUI component" in an iPhone and container for all other GUI components. Therefore we create a pointer to our window, which we will call 'window'.

@property (nonatomic, retain) IBOutlet UIWindow *window;
Properties are more or less instructions to the compiler to generate accessor methods (getters and setters) for a property (member field/variable) of the object. Here we want our variable 'window' to be accessible to other objects, so the compiler will create declarations for it here in the h-file. We also flag the property with 'IBOutlet' so that we can manipulate the it using IB.

Classes/Test1AppDelegate.m

This is the m-file (implementation) of the class Test1AppDelegate.

synthesize window
Instructs the compiler to create the actual accessor method (set/get) definitions (implementation), according to the instructions in the @property declaration in the h-file.

- (void)applicationDidFinishLaunching:(UIApplication *)application {
This method is part of the UIApplicationDelegate protocol and gets called when the application has finished launching(!).

[window makeKeyAndVisible]
This line calls the method makeKeyAndVisible in our window 'window'. What might seem strange here is that we so far hasn't seen any code for creating the window, just a declaration of the window in the h-file. This is because we don't create this window programmatically (in source code), but instead use IB to create, but more on that later.

Resources/MainWindow.xib

This is an IB-file, which was created automatically by XCode when we chose to create a "Window-Based Application" project. We will return to this file soon.

Resources/Info.plist

This is a "property list" which lists same basic properties for the application we are creating. Click it to see its contents. The most important property is the "Main nib file base name" which is set to "MainWindow", meaning that it points to the file Resources/MainWindow.xib in our project. The xib-file listed in the property will be automatically loaded by the iPhone when the application is started.

A first test run

In order to see some action, lets try to build and run our application to see what it does. In XCode, choose "Build/Build and Go" from the menu or simply press CMD-Return. This should bring up the iPhone simulator and display a completely white screen. Not too exciting, but quite impressive considering we still haven't written a single line of code ourselves. Press the Home-button on the iPhone simulator and navigate to the last page of icons on the home screen and you should see an icon called 'Test1' - yes, that's our little application!

Interface Builder (IB)

Ok, now it's time to start exploring the IB. First of all, the most important thing to understand about the IB is that it creates actual Obejctive-C objects and not source code! It can also set the properties of the objects, for example to "connect" two objects two eachother (by setting a pointer in object A to point to object B). The created objects, including the values of their properties, are then saved into a xib-file which can be loaded by the application. When the file is loaded the objects are re-created by the application in run-time. (For Java-coders, this is similar to reading a file containing serialised objects.)

To start IB, double-click Resources/MainWindow.xib. This will start IB and bring up some windows, where the window titled "MainWindow.xib" is the starting point. This window displays the content of a xib-file, in this case our xib-file called MainWindow.xib.

File's owner.

This object represents the object which eventually will load this xib-file - the object which "owns" this xib-file - and that is why it has the very confusing name "File's owner".

In our case, the real object owning this xib-file is the UIApplication automatically created by the iPhone when our application is started. The UIApplication object knows it should load this xib-file since we specified it in the Info.plist file.

The most important tool in IB is the "Inspector window" which can be invoked from the "Tools/Inspector" menu. It has four "tabs" called "Attributes", "Connections", "Size" and "Identity", which can be reached directly from anywhere in IB by clicking on an object icon and then pressing CMD-1 to CMD-4 respectively. In my view, "Identity" (CMD-4) is the best place to start since it tells us what kind of object we are dealing with.

So, click on "File's owner" and press CMD-4. Here we can see that this object is of the class UIApplication. We can also see that this is where the strange name "File's owner" comes from. The most interesting thing we see, though, is that it has a property (or outlet as it is called here) called 'delegate' which has the Objective-C type 'id'. As you probably know, 'id' is an "object pointer", which means that this property should be set to another object. In this case it should be set to an object which implements the UIApplicationDelegate protocol.

To see the value of the 'delegate' property, press CMD-2 to invoke the "Connections"-tab. Here we can see that 'delegate' is set to 'Test 1 App Delegate', which might sound familiar to you if you looked at the other objects in the IB window 'MainWindow.xib' which displays the contents of the xib-file. Thus, it seems as if there exists a connection between the objects "File's owner" and "Test1 App Delegate" which both exist in our xib-file. Please note that the names "File's owner" and "Test1 App Delegate" are IB-names, not the real names of the objects. To see the real names of the objects, or actually the class of the objects, select an object and press CMD-4.

First Responder.

I haven't fully understood the role of this yet, so I will try to explain it later...

Test1 App Delegate.

Ok, let's check the "Identity Inspector" for this one by pressing CMD-4. We see that this object is of the class Test1AppDelegate and that it has an outlet called 'window'. That's the class we defined in Classes/Test1AppDelegate.h and Classes/Test1AppDelegate.m! As you can see, our UIWindow-property 'window' also showed up, thanks to the IBOutlet in Classes/Test1AppDelegate.h

If we check the object's connections by pressing CMD-2, we see that our 'window' property is set to "Window". This means that a UIWindow with an IB-name of "Window" has been created in IB and connected to our 'window' property. If we check the contents of the xib-file displayed in the MainWindow.xib window we see that there actually is an object there called Window. We can also see which objects reference this object, that is, the "reverse connections". In this case we can see that the "File's owner" object has a connection to this object as we explained above.

Window.

Now, we have finally reached a GUI-object! Select the Window icon and press CMD-4 right away. We see that the class of this object is UIWindow. Press CMD-2 to check the connections: apparently there exists a "reverse connection" from an object with the IB-name "Test1 App Delegate". This means that "Test1 App Delegate" uses this Window.

For an object of UIWindow class, the Attributes (CMD-1) and Size (CMD-3) tabs also contain information. Pressing CMD-1 we can see that the background colour has been set to white, so finally we find the explanation for why we saw a completely white display when we test run our application previously! Pressing CMD-3 we can see that the size is set to 320x480 which completely fills the iPhone's display, which always should be the case for windows.

Finally, we have now explained the contents of the xib-file! Do remember that when the xib-file is loaded, the Objective-C objects it contains are created and the properties set in IB are set in the created objects as well. This is the explanation for how so little source code can accomplish so much.

Learning is my drug...

...but what really gives me a high is spreading the knowledge I acquire during my adventures in the world of software development. My favorite areas of exploration include abstract and "underexplained" things, but anything goes as long as I learn something from it.

The subtitle of the blog - "When one teaches, two learns" - is a quote I once heard and really like. As I interpret it, it means that just by trying to explain something to someone else, you, the teacher, will learn even more. This is something most people have experienced since explaining something and answering questions about it often exposes your own "weak spots" - perhaps you didn't understand it as good as you thought? Well, it's a nice quote, so let's not over analyze it. By the way, according to a Google search it seems as if it was Robert Heinlein who first said it.

Coming from a low level background of mainly C and assembler programming on everything from Commodore Amigas to proprietary embedded systems running real-time operating sytems, I will try give this blog a somewhat different perspective compared to the thousands of other Java and iPhone resources and tutorials available.

To summarise, in this blog, I will try to write down things I learn. At the moment I mostly work with Java SE and Apple iPhone development so I guess most of the posts will be related to those two.

A final note. Since I often write down things as I learn them, I will make no claim that the texts I write are 100% correct. Instead they will reflect my current knowledge of the subject and I will probably update an entry as I learn more. Therefore, comments and corrections are highly appreciated!

PS. As you see, there is one post with an older date than this one. I imported that from one of my other blogs, which now no longer exists...