views:

148

answers:

1

Hi, what i'm trying to reach is to display annotation with the city name.

So I have a class MapPoint :

@interface MapPoint : NSObject<MKAnnotation,MKReverseGeocoderDelegate> {

    NSString* title;
    NSString* cityName;
    CLLocationCoordinate2D coordinate;
    MKReverseGeocoder* reverseGeo;
}

@property (nonatomic,readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic,copy) NSString* title;
@property (nonatomic,copy) NSString* cityName;

-(id) initWithCoordinate:(CLLocationCoordinate2D)c tilte:(NSString*)t;

@end

I implemented it like this :

@implementation MapPoint

@synthesize title,coordinate,cityName;

-(id) initWithCoordinate:(CLLocationCoordinate2D)c tilte:(NSString*)t
{
    [super init];
    coordinate = c;
    reverseGeo = [[MKReverseGeocoder alloc] initWithCoordinate:c];
    reverseGeo.delegate = self;
    [reverseGeo start];
    [self setTitle:t];
    return self;

}

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
    NSString* city = [placemark.addressDictionary objectForKey:(NSString*)kABPersonAddressCityKey];
    NSString* newString = [NSString stringWithFormat:@"city-> %@",city];
    [self setTitle:[title stringByAppendingString:newString]];
}

-(void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error{
    NSLog(@"error fetching the placemark");
}

-(void)dealloc
{
    [reverseGeo release];
    [cityName release];
    [title release];
    [super dealloc];
}

@end

Then, in my CoreLocation delegate I use MapPoint like that:

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
  MapPoint* mp = [[MapPoint alloc] initWithCoordinate:[newLocation coordinate] tilte:[locationTitleField text]];
    [mapView addAnnotation:mp];

    [mp release];

}

Now, I have 2 issues I'm not sure of :

  1. Is it correct to put reverseGeo as a data member , or a better option would be to just alloc it inside the initializer and release it inside the didFindPlacemark/didFailWithError delegates(is it even possible to release it there) ?

  2. How can I make sure then when my annotation get displayed I know for sure that the reverseGeo came back with an answer (placemark or error - whatever it is). Maybe it's just wrong to wait for network response and I should leave it like that - I'm just not sure then when/if network response will arrive it will update the annotationView within the MapView accordingly.

Please elaborate as much as you can. Thanks

A: 
  1. It's fine to store it as a data member.

  2. It looks like you're leaving a trail of annotations for the user's current location? If you're supplementing a regular user's-current-location annotation with a "bread crumb trail" showing where the user has been, then you need to wait to add the point to the map until you get the annotation back (if that's the behavior you want). I would either do that by making the class that manages your map be the MKReverseGeocoder delegate (and have it set the title property and then add the annotation to the map in reverseGeocoder:didFindPlacemark) or add a map reference to your MapPoint class and have it add itself to the map in the same callback.

By the way, the documentation for MKReverseGeocoder includes the following text:

  • When you want to update the location automatically (such as when the user is moving), reissue the reverse-geocoding request only when the user's location has moved a significant distance and after a reasonable amount of time has passed. For example, in a typical situation, you should not send more than one reverse-geocode request per minute.
Seamus Campbell
That's more or less what I thought, but then I started thinking about what I wrote in my post.1. You see, getting the placemark is a network request , do I really want to wait till I get it back and not showing the annotation before ? if later i'll update the title property will it reflect on the mapView ?2.right now i'm allocation a new MKReverseGeocoder for every annotation(Inside MapPoint), is this the right way to do it ?or there is a way to use the same one and just changing its coordinate ?
Idan