Wednesday, May 11, 2011

Reading CSV (comma separated value) from Google Geocoder API

An anonymous reader of my blog requested this tutorial so this was his request which I am happy that I was able to fulfill.

In this tutorial I will be showing you how to read the CSV values in iPhone so for this demo the best thing that I had planned was using the google geocoder api as it returns you CSV that’s comma separated data.

Now what is google geocoder API?

Well you must be familiar with the searching stuff that you do with google maps like you search a place and then suddenly you see that place in google map with a pin annotation in it saying that buddy this is the place that you were searching and here it is in front of you.

So in todays post we will be dealing with such code that will help us to get the latitude and longitude of the place that we type in and display that place in map with annotation.

Design View: Here’s a view at our final output kindly design a view that looks like this




So here’s what we are going to do in this application we have a Textfield placed over a map view into the text field we will be typing the name of the cities like Mumbai, Chennai, Delhi etc and on the hit of the return key we will make a call to the geocoder api of google and that geocoder api will return us CSV values including the latitude and longitude of the entered city and then we are going to supply those latitude and longitude to the mapview and add a pin annotation to it.

Step 1: Open Xcode create a windows based application and add a UIViewController subclass file to it and name it myMapViewController and click finish button so now there are two files added into your class group that’s myMapViewController.h and myMapViewController.m file. To run this application successfully we need to add the mapkit framework so add the mapkit framework into the project (If you forgot or don’t know how to do that here’s a link to my previous post on Map Kit framework). Also into the myMapViewController.h file create a function which will be called when the return key is pressed by the user. Since we will be adding annotation in the map then I would request you to read my previous post on map kit with annotations so that you don’t get confused. Here's a look at the myMapViewController.h

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "FinalLocation.h"

@interface myMapViewController : UIViewController <UITextFieldDelegate> {

MKMapView *_mapView;
UITextField *_searchField;
double newlatitude,newlongitude;
FinalLocation *_objAnnotation;
}
-(void)callSearchAPI;

@end


Step 2: So now if you are reading step 2 it means that you have added the map kit framework into your project and have read my post on map kit with annotation or already know how to add annotations, so lets start kickin here’s the code to the function which will be called when the return button will be pressed


-(void)callSearchAPI
{
NSString *googleRequestURL =  [[NSString alloc]initWithString:[NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=csv",[_searchField.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
NSLog(@"Google request URL is %@",googleRequestURL);
NSString *responseString = [[NSString alloc]initWithString:[NSString stringWithContentsOfURL:[NSURL URLWithString:googleRequestURL]]];
NSArray *resultFromGoogle = [responseString componentsSeparatedByString:@","];
//as a good developer we release the memory when the objects are not in use anymore
[googleRequestURL release];
[responseString release];
if([resultFromGoogle count]>=4&&[[resultFromGoogle objectAtIndex:0]isEqualToString:@"200"])
{
newlatitude = [[resultFromGoogle objectAtIndex:2]doubleValue];
newlongitude = [[resultFromGoogle objectAtIndex:3]doubleValue];
CLLocationCoordinate2D cord = {newlatitude,newlongitude};
MKCoordinateSpan span = {latitudeDelta:0.8,longitudeDelta:0.8};
MKCoordinateRegion reg = {cord,span};
[_mapView setRegion:reg];
_objAnnotation = [[FinalLocation alloc]initWithtitle:_searchField.text andSubTitle:@"CSV Demo" coordinate:cord];
[_mapView addAnnotation:_objAnnotation];
}
else {
[_mapView removeAnnotation:_objAnnotation];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"iPhone By Radix" message:@"OOPS!!! no such location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
_searchField.text = nil;
[alert release];
}

}


Code Explanation: The string variable googleRequestURL contains the API url which accepts the city name to be searched from the search textfield, stringByAddingPercentEscapesUsingEncoding is a string function and is used because since you will be sending some data to the web so in case if you have spaces including inside your string like for example "new delhi" so in this case the space will be replaced by %20 that's the only reason why i have used that function


The second string variable responseString will hold the response from the google geocode api that will be in CSV that’s comma separated value, the NSString class has a method called commentSeparatedbystring in that you can supply any string value in which your data is separated example

My, name, is, Radix, and ,I, love, to, blog

So for the string like above you need to write the string as @”,” their and for the string like this

My; name; is ; Radix; and ; I ;love; to ;blog

You need to write @”;” their

commentSeparatedbystring method usually gets the data separated by either , or ; or any dam string you supply as a parameter their in the form of an Array so now you can save the data in the array and print the array or get the data from the array based upon the index position.

In the above code I am storing the data in the array named resultFromGoogle and just manipulated it to get the data from the array
The data returned by the API has the following values

Status ,4,latitude ,longitude

The status would be 200 if the location is valid else 602 and I think the rest values must be understood and I really don’t know what the 4 stands for so am sorry don’t actually have the data for that.

Step 3: Now its time to add the textfield delegate method so that when the user hits the return button the method which calls the api is called and you can see the appropriate location in the map with the annotation.


- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
if([_searchField.text length]!=0)
{
[self callSearchAPI];
}
else {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"iPhone by Radix" message:@"Enter some text to search" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}

return YES;
}



Code Explantion: Now I think I don’t need to explain the code above because its easy and readable what I am doing here

Step 4: Now for wrapping up heres a simple demo for just reading data which is separated from semi colon you may even use comma in that place

+(void)foo
{
NSString *testString = @"Ravi;Dixit;is;ios;developer";
NSArray *resultArray = [testString componentsSeparatedByString:@";"];

for(int i =0;i<[resultArray count];i++)
{

NSLog(@"%@",[resultArray objectAtIndex:i]);

}
}

check the log after executing this function

Step 5: Now add this view to the window by going into the AppDelegate.m file fo your project here’s a view to that code


#import "GoogleGeoCoderAppDelegate.h"
#import "myMapViewController.h"

@implementation GoogleGeoCoderAppDelegate
@synthesize window;
#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    
    // Override point for customization after application launch.
    myMapViewController *obj = [[myMapViewController alloc]init];
  [window addSubview:obj.view];
    [self.window makeKeyAndVisible];
    
    return YES;
}



And finally when you are done you should get a view like this

First View


User searches for Mumbai

User searches for Las Vegas

iHope this post has helped you out for reading CSV values,  any comments good or bad are always welcome until then Happy iCoding and have a great Day. You can also request me a tutorial. 

6 comments:

  1. hi This is Ganesh

    Very helpful Blogs , Very Nicely Explained,

    Thanks

    ReplyDelete
  2. how can i search for all hospitals in a specific place

    ReplyDelete
  3. how can create a route from current location to a specific place

    ReplyDelete
  4. how can i add a place in google earth by using xcode

    ReplyDelete
  5. @Anonymous: Hello you may search for hospitals near you with the help of four square API or with the help of google places. here's the link for google places

    http://code.google.com/apis/maps/documentation/places/#PlaceSearches

    I did some googling for your next question that's the path and i found this

    http://stackoverflow.com/questions/790313/draw-path-on-map-in-iphone

    and for your last answer i really have no clue because i have not work with this kind of requirement.

    ReplyDelete