Skip to main content

iPhone Map Kit - Tutorial and Code

I tried looking for some online resources that could be of some help but did not find any. I was not able to find any good tutorial that explains how can an address be shown on a map with the application. Therefore, I decided to write one and here it is. Hope it will be of some help.

Lets create a simple application which displays the address entered by the user on the map within the application. We’ll call it MapApp.

1. First, create a Window based application and name the project as MapApp.
2. Add the MapKit framework to the project. (Control + Click Frameworks folder -> Add -> Existing Frameworks)
3. Create a new view controller class and call it MapViewController. Add a text field, button and map view to it.

#import
#import

@interface MapViewController : UIViewController {
IBOutlet UITextField *addressField;
IBOutlet UIButton *goButton;
IBOutlet MKMapView *mapView;
}

@end

4. Now create a xib file named MapView.xib. Set its type to MapViewController and add a UITextField, UIButton and MKMapView to it.

Make sure you set the delegate for the mapView to the controller class.

5. Once the view is ready, update the MapAppDelegate so that the view controller and the view is loaded.

- (void)applicationDidFinishLaunching:(UIApplication *)application {
mapViewController = [[MapViewController alloc] initWithNibName:@"MapView" bundle:nil];
[window addSubview:mapViewController.view];
[window makeKeyAndVisible];
}


6. Now, build the app and check if the view appears correctly or not. We now have the UI ready for entering the address and button for updating the location in the map.

7. Add the class for showing the annotation on the location. Lets call this class as AddressAnnotation.

@interface AddressAnnotation : NSObject {
CLLocationCoordinate2D coordinate;
NSString *mTitle;
NSString *mSubTitle;
}
@end

@implementation AddressAnnotation

@synthesize coordinate;

- (NSString *)subtitle{
return @"Sub Title";
}

- (NSString *)title{
return @"Title";
}

-(id)initWithCoordinate:(CLLocationCoordinate2D) c{
coordinate=c;
NSLog(@"%f,%f",c.latitude,c.longitude);
return self;
}
@end

This class will basically show the title and the subtitle of the location on the map.

8. Lets add the function that will be called when the ‘Go’ button is tapped and this will contain the code that will actually display the address location on the map. We call that action as showAddress

- (IBAction) showAddress {
//Hide the keypad
[addressField resignFirstResponder];
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=0.2;
span.longitudeDelta=0.2;

CLLocationCoordinate2D location = [self addressLocation];
region.span=span;
region.center=location;
if(addAnnotation != nil) {
[mapView removeAnnotation:addAnnotation];
[addAnnotation release];
addAnnotation = nil;
}
addAnnotation = [[AddressAnnotation alloc] initWithCoordinate:location];
[mapView addAnnotation:addAnnotation];
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
}

9. The map view basically shows the location based on its latitude and longitude but we have the address in the textual form. Therefore we need to convert this into CLLocationCoordinate2D. Note that in the above code we call the function names addressLocation to perform this conversion.

-(CLLocationCoordinate2D) addressLocation {
NSString *urlString = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=csv",
[addressField.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString]];
NSArray *listItems = [locationString componentsSeparatedByString:@","];

double latitude = 0.0;
double longitude = 0.0;

if([listItems count] >= 4 && [[listItems objectAtIndex:0] isEqualToString:@"200"]) {
latitude = [[listItems objectAtIndex:2] doubleValue];
longitude = [[listItems objectAtIndex:3] doubleValue];
}
else {
//Show error
}
CLLocationCoordinate2D location;
location.latitude = latitude;
location.longitude = longitude;

return location;
}

The above code reads the address entered in the input box and gets the location from maps.google.com in CSV format. It then gets the latitude and longitude from it. The return code of 200 from google means success.

10. Finally, lets add the delegate function that will display the annotation on the map

- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id ) annotation{
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"currentloc"];
annView.pinColor = MKPinAnnotationColorGreen;
annView.animatesDrop=TRUE;
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5, 5);
return annView;
}

This function basically creates a annotation view (a green color pin) with the annotation that we added earlier to the MapView. Tapping on the green pin will display the title and the sub-title.

So this was a very simple example of how a map can be shown from within an application. Hope this was helpful. Let me know your comments/feedback. Click here to download the code.

UPDATE: All this while Google was not looking for API key in the URL - http://maps.google.com/maps/geo?q=address&output=csv

The URL now needs to change to – http://maps.google.com/maps/geo?q=address&output=csv&key=YourGoogleMapsAPIKey

Comments

Popular posts from this blog

Implement Push Notification in iPhone Game or Application

One of the widely anticipated features of the new iPhone OS 3.0 is push notifications which allow messages to be sent directly to an individual device relevant to the application that has been installed. Apple have demoed this as useful for news alerts, or IM notifications however it fits in perfectly with the nature of our server monitoring service, Server Density. As part of the product, we have an iPhone application that includes push notifications as an alerting option so you can be notified via push direct to your iPhone when one of your server alerts have been triggered. This is useful since our app can then be launched to instantly see the details of the server that has caused the alert. Apple provides detailed code documentation for the iPhone OS code that is needed to implement and handle the alerts on the device but only provides a higher level guide for the provider server side. As a provider, you need to communicate with the Apple Push Notification Service (APNS) to s...

Cocos2d Customize Labels and Fonts

cocos2d supports both TTF (True Type Fonts) labels, and texture atlas labels. (Please note that from cocos2d Version .7+ on, the label is added to it's layer via addChild: and not add: e.g. [self addChild:myLabel];) Pros and Cons of TTF labels: ( CCLabel ) * + All the pros of TTF fonts: any size, kerning support, etc. * + Easy to use. No need to use an external editor. * - The creation/update is very slow since a new texture will be created Pros and Cons of texture atlas labels: ( CCLabelAtlas, CCBitmapFontAtlas ) * + The creation / update is very fast, since they don't create a new texture. * + Fonts can be customized (shadows, gradients, blur, etc) * - Depends on external editors: AngelCode / Hiero editor, GIMP / Photoshop Creating labels: Simple way The easiest way to create a label is by using the CCLabel object. Example: CCLabel *label = [CCLabel labelWithString:@"Hello World" f...

Cocos2d Game Development Performance Tips

Cocos2d for iPhone is a wonderful open source framework that makes it easy to draw 2D graphics with OpenGL ES. It allows to you unlock the power of the graphics hardware in iPhone OS devices, without having to deal with all the details of working with GL. Having said that, using Cocos2d is a great way to get your feet wet with GL programming. I’d never done any OpenGL stuff before, but I found I picked up quite a bit as I went along. It handles most of the hard stuff, but it’s very easy to subclass and handle drawing yourself as you become more experienced. When I started working on the bizarre experiment that eventually became Space Harvest, I initially used Core Animation. This is great, up to a point, but I found I soon hit a performance wall - Core Animation wasn’t flexible enough to handle the types of things I wanted to do, and doesn’t really give you a lot of control over what’s happening under the hood. Once I switched to Cocos2d, I found that a) it was a lot easier to get ...