Black screen on first exercise


#1

It has been a few years since I’ve done OO programming, and never with Objective-C, so I’m trying to take this slow and work through each example and understand exactly what is going on. Needless to say, I am very much a newbie with the iOS classes and the reference library.

I have just started chapter 5, having successfully completed chapter 4. I am trying to get the initial build that will ONLY show a map view to display. I don’t want to move on to things like the view problems I’ve seen discussed so far. From the MKMapView class reference, it doesn’t seem like anything I’ve done so far is incorrect, so I must be missing something. But I can’t find it. I’d appreciate some assistance.

Here is my code for WhereAmIappDelegate.h:

[code]#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>

@interface WhereamiAppDelegate : NSObject <UIApplicationDelegate, CLLocationManagerDelegate>
{
UIWindow *window;

CLLocationManager *locationManager;

IBOutlet MKMapView *mapView;
IBOutlet UIActivityIndicatorView *activityIndicator;
IBOutlet UITextField *locationTitleField;

}

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

@end[/code]

And this is my code for WhereAmIAppDelegate.m:

[code]#import “WhereamiAppDelegate.h”

@implementation WhereamiAppDelegate

@synthesize window;

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

    // Create location manager object -
    locationManager = [[CLLocationManager alloc] init];

    // Make this instance of WhereamiAppDelegate the delegate
    // it will send its messages to our WhereamiAppDelegate
    [locationManager setDelegate:self];

    // We want all results from the location manager
    [locationManager setDistanceFilter:kCLDistanceFilterNone];

    // And we want it to be as accurate as possible
    // regardless of how much time/power is takes
    [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];

    // Challenge: print the heading information
    // First turn on the heading updates with the startUpdatingHeading method
    // Then the locationManager:didUpdateHeading method will call the delegate, with the heading
    // [locationManager startUpdatingHeading];

    // Tell our manager to start looking for its location immediately
    // [locationManager startUpdatingLocation];
    [mapView setShowsUserLocation:YES];

    [window makeKeyAndVisible];

    return YES;
    }

  • (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
    fromLocation:(CLLocation *)oldLocation
    {
    NSLog(@"%@", newLocation);
    }

  • (void)locationManager:(CLLocationManager *)manager
    didFailWithError:(NSError *)error
    {
    NSLog(@“Could not find location: %@”, error);
    }

  • (void)dealloc {
    [locationManager release];
    [window release];
    [super dealloc];
    }

@end[/code]

I have also checked the MainWindow.xib multiple times and all of the linkages look correct as far as I can tell:

WhereAmI app delegate has 4 outlets
activityIndicator points to Grey Activity Indicator
locationTitleField points to Round Style Text Field
mapView points to Map View
window points to Window

It also has 3 referencing outlets: delegates
File’s Owner
Round Style Text Field
Map View

Each of the 4 elements in the interface also show that they have a single Referencing Outlet:Window of WhereAmI app delegate.

When I do a build, the console shows that I have the GDB running, and the simulator appears. The app starts, but nothing happens, just the title bar and a black screen. I have downloaded the example files from the web site and compared the files to my files, and they appear to be the same (up to this point, obviously additions that I am about to get to are missing).

Does anyone have any advice?

– I forgot to mention, this is iOS 4.3


#2

Ok, I found the problem. I added the code mentioned on the errata sheet, and that is allowing to work.

For anyone who is having the same problem, the errata sheet for this example is WRONG. Someone notes this in a comment.

The sheet includes the following code:

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation { CLLocationCoordinate2D loc = [userLocation coordinate]; MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 250, 250); [worldView setRegion:region animated:YES]; }

This is incorrect, since “worldView” is not the name assigned to the pointer passed into this method. The correct name is “mapView”. You should instead use the following:

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation { CLLocationCoordinate2D loc = [userLocation coordinate]; MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 250, 250); [mapView setRegion:region animated:YES]; }

This introduces a second problem in that you have already defined “mapView” as an instance variable of a pointer to an MKMapView object. IMO this is poor coding practice, I have always been in favor naming variables and instances using a style that makes it very clear what it is. Something like ptrInstanceMapView.

There are two ways to fix this problem. Easiest is the change the name of mapView in the method that was added to “WorldView”:

  • (void)mapView:(MKMapView *)WorldView didUpdateUserLocation:(MKUserLocation *)userLocation

The other way is to change “WorldView” to “MapView” and change the other “MapView” declaration:

  1. In WhereamiAppDelegate.h change to: IBOutlet MKMapView *ptrInstanceMapView;
  2. In WhereamiAppDelegate.m change to: [ptrInstanceMapView setShowsUserLocation:YES];
  3. Save both files then using Interface Builder in MainWindow.xib delete the now missing mapView and connect the new “ptrInstanceMapView” to the MKMapView opject.

Run a build and the map should now be visible.