Need help for Annotations Challenge


#1

I can’t figure out why the date is not being displayed when I click on the pins on the map.

Here is the code.
//
// MapPoint.h
// Whereami
//
// Created by Billy Irwin on 8/21/11.
// Copyright 2011 MyCompanyName. All rights reserved.
//

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

@interface MapPoint : NSObject
{
NSString *subTitle;
NSString *title;
CLLocationCoordinate2D coordinate;
}

-(id) initWithCoordinate: (CLLocationCoordinate2D)c
title: (NSString *)t
subTitle: (NSString *)st;

@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

@property (nonatomic, copy) NSString *title;

@property (nonatomic, copy) NSString *subTitle;

@end

//
// MapPoint.m
// Whereami
//
// Created by Billy Irwin on 8/21/11.
// Copyright 2011 MyCompanyName. All rights reserved.
//

#import “MapPoint.h”

@implementation MapPoint
@synthesize coordinate, title, subTitle;

-(id) initWithCoordinate: (CLLocationCoordinate2D)c
title: (NSString *)t
subTitle: (NSString *)st

{
self = [super init];
if (self) {
coordinate = c;
[self setTitle: t];
[self setSubTitle:st];
}
return self;
}

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

@end

//
// WhereamiAppDelegate.h
// Whereami
//
// Created by Billy Irwin on 8/21/11.
// Copyright 2011 MyCompanyName. All rights reserved.
//

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

@interface WhereamiAppDelegate : NSObject <UIApplicationDelegate, CLLocationManagerDelegate, MKMapViewDelegate, UITextFieldDelegate>
{
CLLocationManager *locationManager;
IBOutlet MKMapView *worldView;
IBOutlet UIActivityIndicatorView *activityIndicator;
IBOutlet UITextField *locationTextField;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;

-(void) findLocation;
-(void) foundLocation: (CLLocation *) loc;

@end

//
// WhereamiAppDelegate.m
// Whereami
//
// Created by Billy Irwin on 8/21/11.
// Copyright 2011 MyCompanyName. All rights reserved.
//

#import “WhereamiAppDelegate.h”
#import “MapPoint.h”

@implementation WhereamiAppDelegate

@synthesize window = _window;

  • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    locationManager = [[CLLocationManager alloc] init];
    [locationManager setDelegate:self];

    [locationManager setDistanceFilter:kCLDistanceFilterNone];
    [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    [worldView setShowsUserLocation:YES];

    [locationManager setHeadingFilter:kCLHeadingFilterNone];
    [locationManager setHeadingOrientation:CLDeviceOrientationFaceUp];
    [locationManager stopUpdatingHeading];
    [self.window makeKeyAndVisible];
    return YES;
    }

-(void) locationManager: (CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
NSLog(@"%@", newLocation);
NSTimeInterval t = [[newLocation timestamp] timeIntervalSinceNow];
if (t < -180) {
return;
}
[self foundLocation:newLocation];
}

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

-(void) locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
NSLog(@"%@", newHeading);
}

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

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

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

-(void) foundLocation:(CLLocation *)loc
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeStyle:NSDateFormatterNoStyle];
[formatter setDateStyle:NSDateFormatterMediumStyle];
CLLocationCoordinate2D coord = [loc coordinate];
MapPoint *mp = [[MapPoint alloc] initWithCoordinate:coord
title:[locationTextField text]
subTitle:[formatter stringFromDate:[NSDate date]]];
[worldView addAnnotation:mp];
[mp release];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coord, 250, 250);
[worldView setRegion:region animated:YES];

[locationTextField setText:@""];
[activityIndicator stopAnimating];
[locationTextField setHidden:NO];
[locationManager stopUpdatingLocation];
[formatter release];

}

  • (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)dealloc
    {
    if([locationManager delegate] == self)
    [locationManager setDelegate:nil];
    [locationManager release];
    [_window release];
    [super dealloc];
    }

@end


#2

Hey Billy,

I am not sure if this is the problem fully, but I noticed you made a mistake that I also had made. Since MKAnnotation is a protocol, instance variables have already been defined by Apple as to what they should be. Now for subTitle, it should be spelled with a lower case T, so it should be subtitle. Your synthesized setter would then be setSubtitle;

When I made that changed (and realized the mistake :blush: ), it worked perfect. Hope this helps.


#3

Thanks man! Works perfectly now!


#4

I’ve incorporated the date formatting into my code, thanks. You could also simplify the code a bit by moving the date coding to the initWithCoordinate:title method of MapPoint eliminating the need to pass it as an argument.

Byrne


#5

Incidentally, enclosing the code in “code” tags (the button right above where you typed the post here) will preserve the formatting, most importantly the indentation and the fixed-width font, making it easier to read.