Blank Simulator

(2nd Edition, Ch 31, p. 248)

The application runs, and the simulator starts up, but no objects appear in simulator.

Do you have any messages in the Console area of Xcode?

Forgot to mention that I got this message in the console: Application windows are expected to have a root view controller at the end of application launch

Are you using a storyboard or regular xib for the view(s)?

No. This book is my first introduction to Objective C, Xcode and iOS development. I haven’t encountered xib files or storyboards yet.

Could you paste your code please?

Nick

The problem seems to be with the version of Xcode I’m running. I sent the project to someone who’s running Xcode 4 with Simulator 6.1.1, and it works properly on his machine. I’m using Xcode 5 with Simulator 7.0.3, and I get a blank simulator screen. The 2nd edition that I’m reading is supposed to cover Xcode 5. Maybe it’s a setting somewhere that I need to change.

Hmm, not sure there (don’t think it’s a settings issue) - could you paste your code please so that I can have a look at what you have done?

BTW - The message “Application windows are expected to have a root view controller at the end of application launch” is fine for this app as this is not how you would normally do this.

Nick

Thanks for taking the time and trouble to help!

Here’s the code:

//
// BNRAppDelegate.h
// iTahDoodle
//
// Created by John Queen on 1/1/14.
// Copyright © 2014 Big Nerd Ranch. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface BNRAppDelegate : UIResponder

@property (strong, nonatomic) UIWindow *window;

@property (nonatomic) UITableView *taskTable;
@property (nonatomic) UITextField *taskField;
@property (nonatomic) UIButton *insertButton;
@property (nonatomic) NSMutableArray *tasks;

  • (void)addTask:(id)sender;

@end

//
// BNRAppDelegate.m
// iTahDoodle
//
// Created by John Queen on 1/1/14.
// Copyright © 2014 Big Nerd Ranch. All rights reserved.
//

#import “BNRAppDelegate.h”

@implementation BNRAppDelegate

#pragma mark - Application delegate callbacks

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

    // Create and configure the UIWindow instance
    // A CGRect is a struct with an origin (x,y) and a size (width,height)
    CGRect winFrame = [[UIScreen mainScreen] bounds];
    UIWindow *theWindow = [[UIWindow alloc] initWithFrame];
    self.window = theWindow;

    // Define the frame rectangles of the three UI elements
    // CGRectMake() creates a CGRect from (x, y, width, height)
    CGRect tableFrame = CGRectMake(0, 80, winFrame.size.width,
    winFrame.size.height - 100);
    CGRect fieldFrame = CGRectMake(20, 40, 200, 31);
    CGRect buttonFrame = CGRectMake(228, 40, 72, 31);

    // Create and configure the UITableView instance
    self.taskTable = [[UITableView alloc] initWithFrame:tableFrame
    style:UITableViewStylePlain];
    self.taskTable.separatorStyle = UITableViewCellSeparatorStyleNone;

    // Tell the table view which class to instantiate whenever it
    // needs to create a new cell
    [self.taskTable registerClass:[UITableViewCell class]
    forCellReuseIdentifier:@“Cell”];

    // Create and configure the UITextField instance where new tasks will be entered
    self.taskField = [[UITextField alloc] initWithFrame:fieldFrame];
    self.taskField.borderStyle = UITextBorderStyleRoundedRect;
    self.taskField.placeholder = @“Type a task, tap Insert”;

    // Create and configure the UIButton instance
    self.insertButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    self.insertButton.frame = buttonFrame;

    // Give the button a title
    [self.insertButton setTitle:@"Insert"
    forState:UIControlStateNormal];

    // Set the target and action for the Insert button
    [self.insertButton addTarget:self
    action:@selector(addTask:)
    forControlEvents:UIControlEventTouchUpInside];

    // Add our three UI elements to the window
    [self.window addSubview:self.taskTable];
    [self.window addSubview:self.taskField];
    [self.window addSubview:self.insertButton];

    // Finalize the window and put it on the screen
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];

    return YES;

}

  • (void)applicationWillResignActive:(UIApplication *)application
    {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }

  • (void)applicationDidEnterBackground:(UIApplication *)application
    {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

  • (void)applicationWillEnterForeground:(UIApplication *)application
    {
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    }

  • (void)applicationDidBecomeActive:(UIApplication *)application
    {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

  • (void)applicationWillTerminate:(UIApplication *)application
    {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }

#pragma mark - Actions

  • (void)addTask:(id)sender
    {
    // Get the task
    NSString *text = [self.taskField text];

    // Quit here if taskField is empty
    if ([text length] == 0) {
    return;
    }

    // Log text to console
    NSLog(@“Task entered: %@”, text);

    // Clear out the text field
    [self.taskField setText:@""];
    // Dismiss the keyboard
    [self.taskField resignFirstResponder];

}

@end

Unfortunately I cannot see any problem with your code, in fact I have copied/pasted it into a new project and it works for me as expected.

Are you able to supply a zipped version of your project?

For future reference, could you place code between tags, or by clicking on the “Code” button above the editor? This makes it easier to read the code.

Cheers,
Nick

I have the same issue, using 5.02

I have just had a thought - when you created the new project, which template did you use?

You need to choose Empty.

Nick

I’m having the same problem. XCode 5.0.2, iOS Simulator 7.0.

I tried waiting 15 minutes for the black screen to go away as they recommended on the Apple forums, no luck. (The simulator isn’t frozen though, I can go back to home, and resume the application too, no luck.)

(And I confirmed that I started with Empty, and compared my code against the book, and the copy pasted here.)

I can send the project to you. What email address?

Nevermind :slight_smile: (Deleted) - I didn’t have the addTask bit for the Insert button!

I just discovered that if I stop the product (Product -> Stop) the simulator starts working.

Strange one there - glad you are now sorted.

This is expected. Xcode’s complaints are new, but your code is correct.

In this exercise, we have added views directly to the application’s window in the interest of brevity. This is not normal practice, but adopting normal practice in this exercise would’ve made the exercise prohibitively long. Our aim was to acquaint you with some of the basic tenets of iOS development.

If you move on to an iOS Programming book after this Objective-C book, you will be thoroughly introduced to the idea of View Controllers, which is what this exercise has left out.

Fear not, you did everything right.

I am having the same issue as well. This is very discouraging, I feel like throwing this mac out the window since I wanted to learn IOS programming and have gone through every exercise in the book verbatim. Does anybody know how to fix this?
Here is my code and I did an empty solution. All i get is a blank white screen.

//
//  BNRAppDelegate.m
//  iTahDoodle
//
//  Copyright (c) 2014 Big Nerd Ranch. All rights reserved.
//

#import "BNRAppDelegate.h"

@implementation BNRAppDelegate

#pragma mark - Application delegate callbacks

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    CGRect winFrame = [[UIScreen mainScreen] bounds];
    UIWindow *theWindow = [[UIWindow alloc] initWithFrame];
    
    self.window = theWindow;
    
    CGRect tableFrame = CGRectMake(0,80, winFrame.size.width, winFrame.size.height - 100);
    CGRect fieldFrame = CGRectMake(20,40,200,31);
    CGRect buttonFrame = CGRectMake(228,40,72,31);
    
    self.taskTable = [[UITableView alloc] initWithFrame:tableFrame style:UITableViewStylePlain];
    self.taskTable.separatorStyle = UITableViewCellSeparatorStyleNone;
    
    [self.taskTable registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
    
    self.taskField = [[UITextField alloc] initWithFrame:fieldFrame];
    self.taskField.borderStyle = UITextBorderStyleRoundedRect;
    self.taskField.placeholder = @"Type a task and tap Insert";
    
    self.insertButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    self.insertButton.frame = buttonFrame;
    
    [self.insertButton setTitle:@"Inseert" forState:UIControlStateNormal];
    
    [self.window addSubview:self.taskTable];
    [self.window addSubview:self.taskField];
    [self.window addSubview:self.insertButton];
    
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    
    
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

-(void) addTask:(id)sender
{
    
}

@end

Unfortunately, sydouglas, I can’t duplicate your issue. :frowning:

I pasted your code into a new Empty iOS project and am getting the expected result when I build and run.

Is it possible that you chose the “single view application” instead of “empty application” template when creating the project?

I’ve PM’d you my email address. Might you send me a .zip of your project folder so that I can have a better look? A right-click -> Compress of the top-level project folder should do.