MainWindow.xib

[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 responses to “MainWindow.xib”

  1. Bal Avatar
    Bal

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

  2. Madhava Jay Avatar

    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?

    1. Jeroen Trappers Avatar

      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.

  3. Danic Avatar
    Danic

    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!

    1. Jeroen Trappers Avatar

      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

    2. Dmitry Avatar
      Dmitry

      Same here (same book, same problem). This post saved me hours of work. Thank you very much!

  4. Anson Avatar
    Anson

    Awesome…finally figure it out! Thanks man!

  5. […] Click here for the original post! […]

  6. Jeroen Trappers Avatar

    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

  7. David Avatar
    David

    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?

  8. Seth Hein Avatar
    Seth Hein

    Thanks so much for the post. Was very helpful for me.

  9. james Avatar
    james

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

  10. […] “MainWindow.xib” posted by Jeroen Trappers […]

  11. mike Avatar
    mike

    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.

    1. Jeroen Avatar

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

  12. Mathias Avatar
    Mathias

    Thanks a bunch – helped me a lot!

  13. Margi Avatar
    Margi

    Great Tutorial.. THanks a lot Jeroen..

  14. tim Avatar
    tim

    thank you.
    I has been very helpful.

  15. Dave Avatar
    Dave

    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.

    1. Dave Avatar
      Dave

      Nevermind…
      Bit embarrassing but I fixed it.
      Thanks for tutorial.

  16. adam Avatar
    adam

    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 🙁

  17. Syed Rakib Al Hasan Avatar
    Syed Rakib Al Hasan

    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.

  18. Syed Rakib Al Hasan Avatar
    Syed Rakib Al Hasan

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

  19. Jeroen Trappers Avatar

    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

  20. Ron Avatar
    Ron

    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.

    1. Jeroen Trappers Avatar

      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.

      1. Ron Avatar
        Ron

        Ah yes of course.

  21. Iraklii Buziashvili Avatar
    Iraklii Buziashvili

    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

    1. Jeroen Trappers Avatar

      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,

      1. Iraklii Buziashvili Avatar
        Iraklii Buziashvili

        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.

      2. Iraklii Buziashvili Avatar
        Iraklii Buziashvili

        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.

  22. Kent Joosten Avatar
    Kent Joosten

    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?

  23. Syed Rakib Al Hasan Avatar
    Syed Rakib Al Hasan

    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.

    1. Syed Rakib Al Hasan Avatar
      Syed Rakib Al Hasan

      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.

  24. DRL87 Avatar
    DRL87

    I’m having the same issue as Iraklii 🙁

  25. DRL87 Avatar
    DRL87

    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.

  26. dmert Avatar
    dmert

    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?

    1. dmert Avatar
      dmert

      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.

  27. sarah crow Avatar
    sarah crow

    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!

    1. Chris Avatar
      Chris

      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.

  28. Demos Avatar
    Demos

    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.

  29. Felipe Gringo Avatar

    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.

  30. Sally Avatar

    Thanks! This was super helpful.

  31. Newb iOS programmer Avatar
    Newb iOS programmer

    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?

    1. Jeroen Avatar

      Please read the rest of the comments… the question has been asked and anwsered here.

  32. Rafael Avatar
    Rafael

    SUPERB!!! Thanks a LOT for this comprehensive and illustrated tutorial. Amazing!

  33. naSh Avatar
    naSh

    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!

    1. Jeroen Trappers Avatar

      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?

  34. anoop Avatar
    anoop

    Realy Awsm,

    Thanks

  35. aviofans Avatar
    aviofans

    Hi Buddy, this is a great help to me, a beginner in IOS development, thanks a lot.

  36. Kash Avatar
    Kash

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

  37. Kash Avatar
    Kash

    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?

  38. Kash Avatar
    Kash

    Oops! It was because I selected the wrong “User Interface” option 🙂

  39. […] the instructions in a better way. Meanwhile, you can visit the site of Jeroen Trappers in this post is explained in detail how to recreate the […]

  40. Lukas Avatar
    Lukas

    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.

  41. sarab Avatar
    sarab

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

  42. Jose Avatar
    Jose

    Thank you !!! Great tutorial that saved my day !!!!

  43. […] 这里有人介绍了如果从Empty App创建一个Xcode3时代的Window-Based App:http://www.trappers.tk/site/2011/06/16/mainwindow-xib/ […]

  44. […]   阅读:2 浏览数   抢沙发   MainWindow.xib Posted on 2011-06-16 by Jeroen […]

  45. Emmy Avatar

    Great tutorial. Thanks

  46. Bruce Wang Avatar
    Bruce Wang

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

  47. Reid Avatar
    Reid

    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.

  48. DP Avatar
    DP

    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.

  49. […] Application 的解决办法 xcode 4.2 不再支持 Window-Based Application 的解决办法 MainWindow.xib 分享到: var jiathis_config={ summary:"", hideMore:false } iOSiOS, iPhone […]

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.