Help With Reverse Geocoding


#1

Hi all,

I am newbie to programming but am liking the pace of the book so far. However, I am having trouble with this challenge. I don’t know why I can’t do a NSLog to console to print the “placemark properties”. Here is my code. Any help/hints would be appreciated. Thanks.

My AppDelegate.H is:

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>

@interface WhereamiAppDelegate : NSObject <UIApplicationDelegate, CLLocationManagerDelegate, 
											MKMapViewDelegate, MKReverseGeocoderDelegate> {
        UIWindow *window;
	CLLocationManager *locationManager;
	
	IBOutlet MKMapView *mapView;
	IBOutlet UIActivityIndicatorView *activityIndicator;
	IBOutlet UITextField *locationTitleField;
												
	MKReverseGeocoder *reverseGeocoder;
}

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

- (void)findLocation;
- (void)foundLocation;
@end

My AppDelegate.M is:

#import "WhereamiAppDelegate.h"
#import "MapPoint.h"

@implementation WhereamiAppDelegate

@synthesize window;
@synthesize reverseGeocoder;


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
	locationManager = [[CLLocationManager alloc] init];
	[locationManager setDelegate:self];
	[locationManager setDistanceFilter:kCLDistanceFilterNone];
	[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
	[locationManager startUpdatingHeading];
	[mapView setShowsUserLocation:YES];

    [window makeKeyAndVisible];
    return YES;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation 
                                                                                              fromLocation:(CLLocation *)oldLocation
{
	NSLog(@"The new location is: %@",newLocation);
	NSTimeInterval t = [[newLocation timestamp] timeIntervalSinceNow];
	if (t < -180) { 
		return;
	}
	
	NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
	[dateFormatter setDateStyle:NSDateFormatterLongStyle];
	
	NSDate *now = [NSDate date];	// Requests for the date.
	
	MapPoint *mp = [[MapPoint alloc] initWithCoordinate:[newLocation coordinate] title:[locationTitleField text] 
											   subtitle:[dateFormatter stringFromDate:now]];
	[mapView addAnnotation:mp];
	[mp release];
	[dateFormatter release];				
	[self foundLocation];
	
    reverseGeocoder = [[[MKReverseGeocoder alloc] initWithCoordinate:[newLocation coordinate]] autorelease];
    [reverseGeocoder setDelegate:self];
    [reverseGeocoder start];
}

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

// CHALLENGE: Prints the heading information in the console.
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
	NSLog(@"Displaying heading calibration:%@",newHeading);
}

// NEW: this method can initiate zoom whenever a new annotation is added.
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
{
	MKAnnotationView *annotationView = [views objectAtIndex:0];
	id <MKAnnotation> mp = [annotationView annotation];
	MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([mp coordinate], 250, 250);
	[mv setRegion:region animated:YES];
}

- (BOOL)textFieldShouldReturn:(UITextField *)tf
{
	[self findLocation];
	[tf resignFirstResponder];
	return YES;
}

- (void)findLocation
{
	[locationManager startUpdatingLocation];
	[activityIndicator startAnimating];
	[locationTitleField setHidden:YES];
}

- (void)foundLocation
{
	[locationTitleField setText:@""];
	[activityIndicator stopAnimating];
	[locationTitleField setHidden:NO];
	[locationManager stopUpdatingLocation];
}

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error
{
	NSLog(@"MKReverseGeocoder has failed.");
}

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
	NSLog(@"The geocoder has returned: %@", [placemark addressDictionary]);
}

- (void)dealloc {
    [locationManager setDelegate:nil];
    [window release];
    [super dealloc];
}

@end

#2

Hi,

looks like you’re missing “@class MapPoint” in the app delegate .h file.

Gareth


#3

Hi,

Thanks. I have included the @class in my app delegate.h file at the top now, but still having no luck printing the "placemark properties"
to the console.

Any other advice?


#4

Hi,

Try removing autorelease from

reverseGeocoder = [[[MKReverseGeocoder alloc] initWithCoordinate:[newLocation coordinate]] autorelease];

and release it in dealloc instead.

Gareth


#5

Hi Gareth,

Think removing the autorelease has solved the problem. I released it in the dealloc instead. Now I get this error:

/SourceCache/ProtocolBuffer_Sim/ProtocolBuffer-26/Runtime/PBRequester.m:523 server returned error: 503
2010-05-27 14:47:47.813 GeoCoding[306:207] MKReverseGeocoder has failed.

Which you reported you had before on another thread. Guess I should try again at another time and see if it works.
Fingers crossed. Thanks again!!