What is the relationship between AppDelegate, RootViewController, and UIApplication?

guy8214 picture guy8214 · Feb 10, 2011 · Viewed 24k times · Source

I am trying to figure out the relationship between the appdelegate, RootViewControoler, and UIApplication. Here is what I kinda have figured out so far:

When starting your application up, main.m gets loaded.

From here, your MainWindow.xib gets loaded.

In your MainWindow.xib, your File's Owner is of type UIApplication.

You set your UIApplication's delegate to your AppDelegate.

In your AppDelegate's source code, you can set your RootViewController to be the first view shown.

Is this right? What prompts AppDelegate to initially run it's

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { }

method?

Answer

Bogatyr picture Bogatyr · Feb 10, 2011

When an Objective-C application starts, it starts by running the function named main(). It doesn't have to be in the file "main.m" but that's how the Xcode wizard sets things up.

Inside the wizard-produced main() function, there is this line:

int retVal = UIApplicationMain(argc, argv, nil, nil);

That is what starts the "UIKit" framework that makes up the entire application. Inside UIApplicationMain, an object of type UIApplication is created. And part of what UIApplication does when the application starts is call the applicationDidFinishLaunchingWithOptions method on the delegate member of the UIApplication class. This delegate is set up in the MainWindow.xib file to be an instance of your ProjectAppDelegate class, a subclass of NSObject that conforms to the UIApplicationDelegate protocol.

What prompts AppDelegate to initially run it's ...

Because in your MainWindow.xib file you have connected (well the project wizard did the connection actually) the File's Owner (which is the UIApplication object)'s "delegate" outlet to the UIApplicationDelegate object in the the .xib file, and the class of the UIApplicationDelegate is set to your app's UIApplicationDelegate subclass.

And there's nothing magic about "MainWindow.xib", it could be called "Foo.xib", what's important is that the property in your Info.plist file called "Main nib file base name" is "MainWindow". Trying renaming MainWindow.xib to Foo.xib and changing the "Main nib file base name" in your Info.plist to "Foo" and you'll see it still works.

EDIT: more about RootController

Again, there's nothing magic about the so-called "RootController". This is just the name of the UIViewController subclass created for you by the Xcode new project wizard.

The wizard places code in the project for two classes: ProjectAppDelegate and ProjectViewController. The ProjectAppDelegate class contains two outlet members:

IBOutlet UIWindow *window;
IBOutlet ProjectViewController *viewController;

in the MainWindow.xib file, instances of both UIWindow and ProjectViewController are placed, and hooked up to the above outlets in ProjectAppDelegate.

What gets your stuff up on the screen is this code in your ProjectAppDelegate class:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.

    // Add the view controller's view to the window and display.
    [self.window addSubview:viewController.view];
    [self.window makeKeyAndVisible];

    return YES;
}

Again, nothing really magic about this: the project wizard created code that adds your "root" ViewController's view to the window's view, and makes the window visible. Your "root" view controller was create in the .xib file, and hooked up to the ProjectAppDelegate outlet.

It is very instructive to try to create an application entirely by yourself without using any of the files from the wizard. You'll learn a lot about how .xib files work and how they relate to code objects.