Help With Reverse Geocoding


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;

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) { 
	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];




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




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?



Try removing autorelease from

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

and release it in dealloc instead.



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!!