How to Create an Xcode 4.0-style Window-based Application in Xcode 4.2

I’ve decided to get up to speed on iOS programming and, to help me with that, I bought Aaron Hillegass’s iOS Programming: The Big Nerd Ranch Guid 2nd edition. I’ve listened to Aaron on podcasts and have heard that his training method is fantastic. The book does seem to be unusually well written for a tech book but the problem I immediately ran into is that it was written for Xcode 4.0 and iOS 4.3 SDK. I have Lion with Xcode 4.2 and iOS 5 SDK. That’s part of the adventure of discovery and change in tech but unfortunately Apple removed the project type that Hillegass’s examples are based on which is a major stumbling block.

Hillegass uses the “Window-based Application” template for iOS as the basis for all of his projects. That template no longer exists in Xcode. The closest thing in Xcode 4.2 is “Empty Application”. However, that’s not quite the same thing because the now-defunct “Window-based Application” template generated a main window XIB view wired to generated controller but the “Empty Application” has no XIB. In order to make any sense out of the book, you have to create the XIB and wire it up yourself. This is no big deal to anybody with a little experience but to a newb like me, it took a bit of wandering in the wilderness at the Big Nerd Ranch forums to figure out how to manually get the project into the state that the exercises in the book will work.

How to Convert a new “Empty Application” into a “Window-based Application”

Start by creating a new iOS Application project using the “Empty Application” project. This will create a very similar project to the “Window-based Application” project described in iOS Programming 2/e with just a few differences:

  1. The main controller class that gets generated is “AppDelegate” rather than “<project-name>AppDelegate”. The
  2. There is no XIB view.
  3. The window property of AppDelegate doesn’t have the IBOutlet macro to make it visible to the Interface Builder tooling.
    1. Prepare the controller to talk to the Interface Builder tooling

    In the controller class interface definition of the we need to add the IBOutlet macro so that the tooling will recognize the controller. In your controller header file, AppDelegate.h, the line to modify begins with @property and ends with *window. Add IBOutlet in front of the UIWindow type as shown below.

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

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

@end

Save this change.

Update the didFinishLaunchingWithOptions: method

The auto-generated first line of code in the didFinishLaunchingWithOptions: method of AppDelegate.m prevents message routing from working properly. Comment it out as below:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

Save this change.

Create the XIB file

Right-click on the folder containing your AppDelegate files and choose “Add File”. Select “Window” from the iOS User Interface group. Choose the appropriate device family—for the initial Quiz project that is iPhone. The default file name is Window.xib which works fine or you can name it MainWindow.xib to make it just like in the book.

OS X 10.7 (Lion)-2011-11-23-11-18-56

Change the Class of the XIB file’s owner to UIApplication

Select Window.xib in the Navigator. Select the “File’s Owner” cube in the objects pane just left of the layout canvas and change the Class in the properties pane to UIApplication.

OS X 10.7 (Lion)-2011-11-23-11-34-47

 

Add an object for the controller

Filter the tool pallet on the bottom right to “Objects and Controllers” and drag and drop an Object from the toolbox onto the object pane.

OS X 10.7 (Lion)-2011-11-23-11-37-52

Set the class of the controller object

In the properties window, change the class to controller that was generated for your project by the template. That should be AppDelegate. The Object will automatically be renamed with a space added into the Pascal casing. (You can override this by putting something into the Label field of the Identity pane.)

OS X 10.7 (Lion)-2011-11-23-11-45-00

Route the XIB delegate to the controller

Now we want to wire up the MVC message routing for the view. Select the “File’s Owner” cube in the object pane and control+drag the delegate outlet to the App Delegate object.

OS X 10.7 (Lion)-2011-11-23-12-00-15

 

Route the controller object’s window outlet to the window object

Next perform a similar ctrl+drag of the window outlet from the App Delegate object to the Window object.

OS X 10.7 (Lion)-2011-11-23-12-01-08

All done

Now our Empty Application project is set up just like a Window-based Application as described in iOS Programming 2nd Edition. The file names may be a bit different but that should have no practical  effect. The AppDelegate inherits from UIResponder <UIApplicationDelegate> rather than NSObject<UIApplicationDelegate>. This doesn’t seem to be a problem, either.

Now that I have figured out how to create an wire up a main window XIB file, everything seems to work great as I follow along in the book.

56 Responses to How to Create an Xcode 4.0-style Window-based Application in Xcode 4.2

  1. Hello!!!
    You Rock! thanks for sharing!!!

  2. Michael J. says:

    Thanks – I just hit this a few hours after you did. Appreciate the detailed writeup.

  3. Mark harmon says:

    Wow you are not only a genius, you are a cool one!!!

    Thanks

  4. Demos says:

    Many thanks.

    I followed your instructions and the app runs but I get this error message on the console:

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

    How do I get rid of that?

    • Brian Reiter says:

      I’m pretty sure this is not an error per-se but just guidance that a better-designed app would have used a View Controller object rather than adding views directly to the Window canvas. It should be taken care of when View Controllers are introduced later in the book. Mind you, I haven’t gotten that far myself. Don’t take my assertion as definitive.

    • Ben says:

      I solved this issue by following the first point from Oscar below: “Add “Main nib file base name”: My nib-file name (without .xib) to the -Info.plist”

      Great post!

  5. Oscar says:

    Great info.

    I had to do two extra steps though.

    1. Add “Main nib file base name”: My nib-file name (without .xib) to the Info.plist

    2. Remove the first line (“self.window = …”) in didFinishLaunchingWithOptions.

    Hope that helps someone.

    • Mitch says:

      Re-read Brian’s instructions several times, still didn’t work until I added the row to Info.plist. Thanks so much to the both of you.

    • Mario Zepeda says:

      Thanks a lot, I followed my self Brian’s instructions step by step and it wasn’t working, this was the last thing I had to do, thanks to both of you for sharing.

    • jgasteiz says:

      wow, thank you man! i’ve been stucked there for a while ^^

    • Thank you – just what I’ve been looking for!
      But your second step was done by Brian in the second step as he comments this line…

  6. Brian Reiter says:

    @Oscar: You’re right. I forgot that I had done the modification to didFinishLaunchingWithOptions:. Without commenting out the first line there, the click messages don’t get routed. I did’t have to do any plist editing to get it to work, though.

  7. Pingback: Getting started, and all that that implies « iDevice Development

  8. Mark Thalman says:

    I started with a version of the Quiz app that is just the base project. I found the project at the BNR Forums (http://www.bignerdranch.com/solutions/Quiz.zip) This is what you get when you create a new project with the “Window Based Application”.

    I created a git repository in that folder (git init) and to start a new sample from the book I create a new branch (git branch Chapter_04) and check it out (git checkout Chapter_04). Work in that branch for the chapter. When you are done switch back to the master branch (git checkout master) when you start another chapter and repeat (git branch Chapter_05).

    That way I didn’t have to recreate all this work for every chapter.

  9. Thanks – that looks like useful information. I am starting on Aaron’s book too, and have the same issue. I hope it didn’t take too long for you to figure all this out.

  10. Christian says:

    Don’t we want to set the mainwindow Property of the project?

  11. David says:

    Thanks for this! I have a different book to learn iOS programming but it also uses the Windows based app template for a large number of projects. Your research and post saved me a lot of time!

  12. James says:

    After struggling with all of the wiring up over the last few hours this article helped tremendously!

  13. RLH says:

    I wanted to add my voice to the chorus of praises. I, too, am going through a book that references creating a Windows-based Application, so imagine my frustration when it wasn’t available. Thanks for helping fill in the gaps.

  14. Maarten D says:

    I’m also going through the big nerd ranch guide. Wish I found this page a lot sooner! Thanks for the help, also about the plist file, I finally got some working examples.

  15. Alistair says:

    Thanks! That totally helped me through the first chapter of Aaron Hillegass’ book 🙂

  16. Paul Pollock says:

    An excellent article Brian, should you be in my ‘hood I will gladly purchase for you a beverage of your choice. As you pointed out, this is a common problem with us noobs trying to learn X-code: Apple changes the SDK making it difficult for us trying to learn it to follow tutorials.

  17. Chris says:

    You guys are a huuuuuuuuuuuuuge help. Been trying to get through chapter 1 for a few days now cuz i couldn’ solve this problem. Excellent info guys. Thanks!!

  18. Maitri Shah says:

    Great….Thanks a lot!!!!

  19. alexandru says:

    The article is great, however this is overlooked and essential, maybe you can update de article.

    Add “Main nib file base name”: My nib-file name (without .xib) to the Info.plist

    Example: “Main nib file base name”: MainWindow

    Thanks

  20. Prakash says:

    Thanks

  21. LuMe96 says:

    Also just wanted to say THANKS.

    I had figured out most of it, except adding the MainWindow to the .plist file.

    Great help!!!!

  22. Pyoungwon says:

    Thanks.
    Its amazing. 🙂

  23. morpheo69 says:

    Thanks mate!! Great tutorial and very useful. Thanks a lot

  24. morpheo69 says:

    I almost forget it! Although it’s working I still having the text “Applications are expected to have a root view controller at the end of application launch” into the console.

    Any idea??.

    Thanks.

  25. lilBit says:

    Thanks! Now I can continue using this book to learn iOS.

  26. Mario Zepeda says:

    Just to share this help me to go on with the book “Beginning iOS 4 Application Development” in which they use the window based template a lot, thanks for the help.

  27. Carl says:

    Great info! But I have a problem.. When I go to do the 8th step of connecting the App Delegate’s window outlet to the Window object I see no window outlet… Does anyone know why that is the case?

  28. Syed says:

    Hi
    Thanks for this info I was stuck to just like every one els. I have just tried to run the program and it is giving me an error message at the AppDelegate.m file. next to the – (id)init code it is saying the following: Thread 1: breakpoint 1.1 2.1

    and the same thing at this line in the main.m file

    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

    did any one els have this problem or know why it is saying that?

    any help in this will be much appreciated

    Thanks

    • Brian Reiter says:

      Syed. Xcode is probably not breaking where the exception happened. Try adding an “exception breakpoint” that breaks on throw. That may help you find your problem.

      • syed says:

        Hi Brian. Im new to xcode so dont know what that ment, also i fogot to mention that when the application displayed the iphone it was just a black screen, so it did not work the way its supose to.

        Also I did not do the 2 extra steps explained by Oscar because it did not make sence to me. Do you think that might be why its not working?

  29. Pingback: Learning iOS – “Window-based Application” in XCode 4.2 | Ktatsiu's Blog

  30. asdsa says:

    Brilliant!!!!

  31. Suwigya says:

    genius man live long

  32. andymac says:

    Thanks!
    One wee hiccup … in your last 2 screenshots, I see on my mac the option ‘delegate’ under outlet, but I can’t seem to find ‘window’ :/ thanks mate tho, this is amazing!!

  33. Arturo says:

    So easy, thanks a lot !!

  34. Garren says:

    You, sir, are my hero. I just spent WAY more time than I’d like to admit trying to get a simple example from another book working against xcode 4.4 for the same reason – no Windows Based project template. For the record, this works great in 4.4! My day hasn’t been a complete waste!

  35. Dave says:

    Got the same problem like others here:

    I can’t find the window-Outlet!

    Anyone knows how to solve this?

  36. sophiacui says:

    If anyone is getting a black screen when running the simulator, you may need to update the [AppName]-info.plist with the following row entry:

    Key: Main nib file base name
    Value: MainWindow (or Window)

    • Al says:

      Same problem, I can’t find the window-Outlet either. Those who solved it, could you help us out? Thanks!

      • Al says:

        Fixed it, I had the wrong custom class name for the app delegate. In my case, WBAAppDelegate.h so WBAAppDelegate was the proper custom class. Thanks for this writeup!

  37. This worked brilliantly thanks :). For Those having the problem of not finding the window outlet, you have to use the exact name of your app Delegate not just plain “App Delegate”.
    Cheers

  38. vijaykumar says:

    U r amazing… Thank you

    • Paulo says:

      Click on the root folder(blue icon) on your project, after that click on the tab Summary, in the Main Interface Field choose Window or MainWindow

  39. Pingback: ios rootViewController初始化的一些问题 | yudun1989

Leave a comment