Monday, 6 February 2012

USING IPHONE SDK MAPKIT FRAMEWORK - A TUTORIAL

Recently I was working on an application in which the map was required to be shown with in the application itself. 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 <UIKit/UIKit.h>
    #import <MapKit/MapKit.h>

    @interface MapViewController : UIViewController<MKMapViewDelegate> {
        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. This how it will look like.
Media_httpmithinfiles_auicu
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<MKAnnotation> {
        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 <MKAnnotation>) 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.
Finally, here's how the map looks like when loaded.
Media_httpmithinfiles_sjecp
Media_httpmithinfiles_cyciy
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
You can obtain your API key here

0 comments:

Post a Comment

 

Copyright @ 2013 PakTechClub.