[Update: I added a screencast of the process]
[Update: Interesting discussion of this post over on StackOverflow]
In the XCode 4.2 beta, MainWindow.xib is no longer included by default in some project templates. This means that you have to get your application to work by writing some code, using another method, or by manually reconstructing MainWindow.xib. This post shows the latter. Let’s get started.

If you create a new project in XCode 4.2 beta, and choose the Empty Application template to start from, change nothing and try running it in your iPhone 5.0 simulator, you will see an empty – black – screen. The only thing you get from the template is an xAppDelegate.h and .m.
We will now reconstruct our own MainWindow.xib, to get started with development the way you’re used to. So the next thing we do is add a New File to the project. Choose iOS > User Interface > Empty as template.
Next, choose iPhone, next give it the name MainWindow (.xib will be added automatically). By the way, the name of the file is not very important, but it’s nice to choose MainWindow, because that’s familiar.
Select the new File we just created. What we have now is an empty design surface, in what used to be Interface Builder. Here we’re going to change some things.

- Change the class of File’s Owner to UIApplication

- Find Object in the Library and drag it onto the Objects pane on the left.

- Change the class of that Object to the xAppDelegate class that was created by the template, you might also want to clear out the “Object” label.

- Add a Window to the Objects pane on the left.

Now, let’s bind it all together. To do this, we first need to change some of the code in the xAppDelegate.h. We have to add IBOutlet to the window property it has, so that we can hook it up in Interface Builder. The xAppDelegate.h should read something like this:
@interface DemoAppDelegate :
UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) IBOutlet UIWindow *window;
@endDon’t forget to save the file, otherwise Interface Builder will not be able to pick up the Outlet. Next we continue editing the MainWindow.xib
- Control-Drag from the delegate outlet of the File Owner to the xAppDelegate object.

- Control-Drag from the window outlet of the xAppDelegate to the Window.

- Just for this demo, I’m adding a label to the window.

We’re not done yet, but we’re almost there.
- Navigate to the project, and in the Summary tab, select MainWindow as the Main Interface.
You can now run the project in the Simulator, and the window should show up. However there’s one last thing you might want to clean up. In xAppDelegate.m, there was actually code that creates a window as well. Just put the method
- (BOOL) application:didFinishLaunchingWithOptions:
in comment.

I hope this helps to understand exactly how an iOS app starts. The next thing you should do is add a ViewController, and push it onto the MainWindow. I’m not going to cover that here. Please leave your feedback in the comments.
kthxbye




[I'm a "newbie" (i.e. very recently enrolled as an Apple iOS developer, at the moment trying to navigate through Objective-C, iOS, Xcode, etc., etc.) and I've not used any version of Xcode prior to 4 (currently using 4.2 beta). I was trying to follow along a walkthrough in a book which was written for Xcode 3.1, and they were talking about the MainWindow.xib file while using the single-view application template which I didn't have... as you might guess, Googling brought me to your page.]
Its a weird occurance but I had an iPad application that worked fine with no xib then I installed xcode 4 and it wouldnt work.
So I have re-constructed MainWindow.xib as per your instructions and now it works.
What I don’t understand is, how can we go back the other way?
You seem to suggest in your tutorial that apple is pushing towards not having to have an empty XIB just to have your project working, so can you do a tutorial which shows how to build it all via code?
Hi Jay,
if you would go the other way: not using MainWindow.xib, you would write some code in the app-delegate to set up your application. Namely create and initialize a rootcontroller, and setting it as the value for the rootcontroller property on the app-delegate. That’s also nice; it’s more code, but you have full transparancy of what is going on and how everything is hooked up.
You don’t even have to set the rootcontroller property, you can also add the view of the rootcontroller as a subview of the app-delegate.
many options to choose from.
@property (strong, nonatomic) IBOutlet UIWindow *window;
That is actually what I was googling on when I hit your page.
Again, thanks much for the post!
That’s part of the new Automatic Reference Counting (ARC) Liftetime Qualifiers. It says to the compiler that you want to keep the object alive that that property is referring to. The alternative is weak. That means that the window could be destroyed underneath your feet.
(this documentation is still in beta, so be careful. Also, you need to have a valid developer licence to see it.)
Read more about that here: https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ARCProgrammingGuide/Introduction.html#//apple_ref/doc/uid/TP40011029-CH1-SW4
Pingback: MainWindow XIB problem « LonelyTango
Hi Danic,
the strong keyword in
@property (strong, nonatomic) IBOutlet UIWindow *window;
has to do with the New LifeTime Qualifiers in Automatic Reference Counting (ARC). It means that the runtime needs to keep the object alive that the property references. The alternative would be weak, which means that the runtime could remove the window from under your feet.
See the reference documentation for more info.
Note that this documentation is still in beta, and isn’t open to none-registered apple developers.
Hope this helps,
Kind regards,
Jeroen
Pingback: MainWindow.xib absence in Xcode 4.2 beta 4 with iOS 5 SDK | Chris' Laboratory
Some code here to show you how:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ControlFunViewController alloc] initWithNibName:@”ControlFunViewController” bundle:nil];
self.window.rootViewController = self.viewController;
// or use this: [self.window addSubview:[self.viewController view]];
[self.window makeKeyAndVisible];
return YES;
}
I has been very helpful.
After I changed the class of File’s Owner to UIApplication, there was no “Object” in the Object library so obviously I couldn’t continue. Help would be much appreciated.
Thank You.
Bit embarrassing but I fixed it.
Thanks for tutorial.
Attribute Unavailable
Defines Presentation Context is not available prior to Xcode 4.2
So whats going on? any idea?
Apple ruined this for the noobs
i think you actually meant to modify the appdelegate.m file to comment out only the first 3 lines of the method instead of the entire method itself.
“modify appdelegate.m file to comment out the first 3 lines in the method
- (BOOL) application:didFinishLaunchingWithOptions:”
instead of
“commenting out the entire method
- (BOOL) application:didFinishLaunchingWithOptions:”
Hi Syed,
no, actually you can comment out the entire method, but it is still a useful place to put application initialization code. You don’t need it any more to set up the main view controller of link the window and so on. That is now being handled by the mainwindow.xib.
kind regards,
Jeroen
Hi Ron,
Thank you for the feedback. This blog post is created especially to teach people the inner workings of mainwindow.xib, but you are absolutely correct.
Kind regards.
Hi Iraklii,
maybe you misunderstood, but you have to manually create that IBOutlet, by typing it in the source file for the app delegate.
Hope this helps,
What I meant is I do all the steps described including the 1st connection (delegate). Then when I click on Demo App Delegate, there’s no Outlet with ‘window’ on the righthand side, to connect it with my Window in the Objects.
Thanks a lot.
Thanks.
An IBOutlet needs to be added into the AppDelegate.h‘s UIWindow declaration.
And also, the Class of the AppDelegate object that gets created inside the MainWindow.xib needs to be changed to AppDelegate – as by default it is actually set to NSObject.
And after that, the AppDelegate object’s UIWindow outlet needs to be mapped to the Window as it is not done automatically.
Iraklii, change your object custom class to the same title as your AppDelegate.h file
Hence if your AppDelegate file is AppDelegate.h then make your Object Class “AppDelegate”
They must be the same name.
but I wonder, we never call [self.window makeKeyAndVisible] and the window is shown, how is that possible?
“Applications are expected to have a root view controller at the end of the application launch”
Thanks.
This change on the XCode just was a real spit on the ass.
I’ll be posting about this on my blog and putting your references.
Live long and prosper, peace.
however, an error message “applications are expected to have a root view controller at the end of application launch”
but i did delete the first code in application didFinishLaunchingWithOptions part … so what do i do?
Attribute Unavailable
Defines Presentation Context is not available prior to Xcode 4.2
How can I eliminate this warning? And what does it mean?
Best!
I have no idea when this problem occurs or how to fix it. If someone knows, please feel free. Could you provide more information on what exactly you did?
Pingback: Beginner steps: iOS first apps tutorials « Web 2+ Craftsman's journey
Thanks
At the step “Control-Drag from the delegate outlet of the File Owner to the xAppDelegate object” I can’t see the delegate outlet in the right. All I see is a “New referencing outlet.”
I can’t see where I’m going wrong.??
1) File’s Owner
2) First Responder
3) Application.
Where did Application come from?
Pingback: Christianhv's Blog
Pingback: 五一假期好像啥也没有干 - Glob Studio