[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.

Start with Empty Application template

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. Add Empty Interface Builder documentNext, 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.

The empty design surface of MainWindow.xib

  • Change the class of File’s Owner to UIApplication

Change class of File's Owner to UIApplication

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

Add Object to the document

  • 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.

Change class of the object to xAppDelegate

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

Add a window to the document

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;
@end

Don’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.

Link the application delegate

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

Link the window outlet of the app delegate

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

Add a label for testing

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.

Set the Main Interface to MainWindow

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.

we're done

 

 

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

67 thoughts on “MainWindow.xib

  1. Excuse my ignorance, but what is the significance of the MainWindow.xib file that you would want to reconstruct it? What do we lose by not having it? Why not work directly with the ViewController.xib file?

    [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.]

    Reply
  2. Hey man, AWESOME tutorial, thanks a million.
    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?

    Reply
    • 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.

      Reply
  3. I’m working through iPhone Programming from the Big Nerd Ranch and would have died a quick death without this post. Thanks. I would be curious if you know what the “strong” keyword is all about in the Property declaration:

    @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!

    Reply
  4. Pingback: MainWindow XIB problem « LonelyTango

  5. 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

    Reply
  6. Thanks man, great tutorial, but how do i push a view controller onto the MainWindow.xib file? Ive got a few views along with the MainWindow one. So how would i make what’s in the other views, appear in MainWindow?

    Reply
  7. Thanks for taking the time to put this all together. I was on the right track but missing a few key pieces – you tied it all together. I didn’t have to spend my first night wrestling with what used to be “default” behavior. 🙂

    Reply
  8. Pingback: MainWindow.xib absence in Xcode 4.2 beta 4 with iOS 5 SDK | Chris' Laboratory

  9. Great tutorial. I wanted to know how i add a view controller and push it on the main window. I am new to developing so any help will be appreciated. Thanks.

    Reply
    • Hi Mike, you should do that in the appDelegate. on application:didFinishLaunchingWithOptions: you just push the view you want onto the window.

      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;
      }

      Reply
  10. Unfortunately this didn’t work for me.
    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.

    Reply
  11. I am trying to make your example work but I keep getting a warning saying:

    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 🙁

    Reply
  12. in the last instruction about commenting out the method – (BOOL) application:didFinishLaunchingWithOptions:
    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.

    Reply
  13. in the last instruction about commenting out the method, i think you tried to mean

    “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:”

    Reply
  14. 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

    Reply
  15. A way to make this a little easier, when you add the .xib file into the project: Instead of adding an empty interface file (“iOS -> User Interface -> Empty”), add the type ‘Application’. It creates an xib already setup exactly this way, you just need to specify the app delegate’s class.

    Reply
  16. I have no Outlets with window in it… So can’t make the second connection 🙁 Have no idea what I did wrong. I redid everything like 3 times… Thanks for help

    Reply
    • 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,

      Reply
      • I did.

        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.

        Reply
      • I’m trying to figure out what’s my problem. Looks like the change in code (IBOutlet) is not seen for whatever reason. My source file is AppDelegate.h, with no actual name of the project in from of it (‘x’, like DemoAppDelegate.h or TestAppDelegate.h) although I named it in the beginning. Can that be the reason why the source file ‘is not seen’ and therefore IBOutlet does not give me ‘window’ to connect with it?

        Thanks.

        Reply
  17. A million thanks. The only issue I still have is the “Applications are expected to have a root view controller at the end of the application launch” in debug. Any guidance on how to fix that?

    Reply
  18. There is still work that needs to be done for this.
    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.

    Reply
    • this was actually a reply to Ron’s post where he mentions creating NewFile->UserInterface->Application instead of creating NewFile->UserInterface->Empty takes care of everything.

      Reply
  19. Figured it out.

    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.

    Reply
  20. Commenting out – (BOOL) application:didFinishLaunchingWithOptions: and the application works fine,

    but I wonder, we never call [self.window makeKeyAndVisible] and the window is shown, how is that possible?

    Reply
    • I guess it has to do with setting Mainwindow as the main interface. The runtime itself looks there to see if there is a UIWindow instance and shows it, I suppose.

      Reply
  21. I am a very new (newer than newbie) to the iOs programming. I am in a class for designing iOS apps. The book however gives the directions in iOS 3 and the Xcode i am using is in iOS 5, i was able to use this and make the MainWindow.xib, but don’t understand the push reference or the code you put when Mike asked about the ViewController. Any info would be awesome!

    Reply
    • Remember to do the last step. Define the main interface as MainWindow. I inadvertently skipped this step and had the same problem. I found a video that showed exactly the same thing as this site, but since it was a video I didn’t miss the last step 🙂 My oversight was the problem.

      Reply
  22. I’m having the same problem as Kent. The app runs but I get this error message in the console:

    “Applications are expected to have a root view controller at the end of the application launch”

    Thanks.

    Reply
  23. Bro, thank you very very much.
    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.

    Reply
  24. i did all this and ran the app….
    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?

    Reply
  25. Nobody answered Adam’s question:
    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!

    Reply
  26. Pingback: Beginner steps: iOS first apps tutorials « Web 2+ Craftsman's journey

  27. Hi,

    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.??

    Reply
  28. Come to think of it, my workspace has one other difference – under Placeholders, I have three entries as opposed to the two in your screenshots:
    1) File’s Owner
    2) First Responder
    3) Application.

    Where did Application come from?

    Reply
  29. Pingback: Christianhv's Blog

  30. Thank you very much! I didn’t know how to start with a window-based application in Xcode 4.2.1. I’ve seen many tutorials, but this was the only one, which helped me.

    Reply
  31. Thanks lot for this helpful article. With new ios 5 and old books, this article is great help for beginner.

    Reply
  32. Pingback: 五一假期好像啥也没有干 - Glob Studio

  33. Pingback: Cannot find the windows outlet for the Object in iOS | PHP Developer Resource

  34. Pingback: xcode4.2手动添加MainWindow.xib | 掌中天际

  35. Great post! I wanna know how did know the method, did you figure it out by trying for many times?

    Reply
  36. Pingback: Xcode 4.2 is missing a .xib file?

  37. When using XCode 4.3.3, for some reason I was unable to drag an “object” from the library into the “Objects” pane in the nib. However, double-clicking it added it automatically. Very odd. I thought I’d share in case someone else ran into this issue. Great tutorial, thanks! I’m using an older book and although the “single-view application” template is roughly equivalent to the old “view-based application”, it doesn’t work for many of the exercises in the book and I don’t yet know enough to adapt. Creating this template has solved the problem.

    Reply
  38. Great tutorial! It took me half an hour to fix a problem that I was having, though–I typed the ‘Main nib file base name’/’Main Interface’ field with the .xib file extension, and that didn’t work — it was creating an “internal inconsistency exception — could not load nib”. Just in case someone suffers the same silly problem.

    Reply
  39. Pingback: XCode 4.2 Not Support Windows-Based Application Anymore

Leave a Reply