Google Maps – iOS, Location tracking, Custom Markers, Multiple Markers StreetView, CameraView, IndoorView, Showing Route in Maps etc…

By | February 11, 2016

You know for using Google Maps,we need an API Key.

You can check Google Maps for Android here…

So for that we need to register in Google Developer Console.

 

Google Maps iOS

 

Once you get your API Key. we can start with Integrating Google Maps in our app.

I am going to show how we can integrate The Google Maps SDK library in our project.

For that Open a Terminal and execute command

[java]

sudo gem install cocoapods

[/java]

Now it will ask for Password and Enter your Mac Password.

Once the installation is complete…Navigate to your project directory in the Terminal itself.

You can do this by

[java]

cd "PATH TO YOUR PROJECT"

[/java]

Then execute command…

[java]

touch Podfile

[/java]

This will create a PodFile in your project directory.

Now Open the PodFile

[java]

open -e Podfile

[/java]

Now Enter these in your PodFile and save…

[java]

xcodeproj ‘PATH TO YOUR PROJECT’
source ‘https://github.com/CocoaPods/Specs.git’
platform :ios, ‘8.1’
pod ‘GoogleMaps’

[/java]

Now come back to terminal and execute

[java]

pod install

[/java]

CocoaPods installation set up for Google Maps for iOS is now complete.

You can have a look at the Google’s Documentation for iOS.

Make sure you add this to your info.plist file as shown in the image below.

[java]
<key>NSAppTransportSecurity</key>
<dict>

<key>NSAllowsArbitraryLoads
<true></true>
</dict>
[/java]

 

Google Maps iOS
Now we will go and integrate the SDK in the app..

Now you need to open the .xcworkspace project in XCode after installing CocoaPods.

Our Page Layout will looke like this..

 

Google Maps iOS

 

Open Your AppDelegate.m file and add these…

[java]

@import GoogleMaps;

[/java]

Also

[java]

– (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[GMSServices provideAPIKey:@"YOUR_API_KEY_HERE"];
return YES;
}

[/java]

Now in the ViewController.h

[java]

@import GoogleMaps;

@interface ViewController : UIViewController&lt;GMSMapViewDelegate, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource&gt;
{
GMSGeocoder *geocoder_;
NSArray *tableData;
}

@end

[/java]

ViewController.m

Import UIKIT also…

[java]

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController{
GMSMapView *mapView_;
__weak IBOutlet UITextField *searchTF;
__weak IBOutlet UIView *mapParentView;
__weak IBOutlet UITableView *optionsTV;
int ZOOM_LEVEL;
}

– (void)viewDidLoad
{
[super viewDidLoad];

ZOOM_LEVEL = 6;

searchTF.delegate = self;

[self showLocation:NO];

tableData = [NSArray arrayWithObjects:@"Location", @"StreetView", @"Camera", @"Indoor", @"Custom Marker", @"Show Route",nil];

}

– (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableData count];
}

– (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = @"SimpleTableItem";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}

cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}

– (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
int index = (int) indexPath.row;
if(index == 0)
[self showLocation : NO];
if(index == 1)
[self showStreetView];
if(index == 2)
[self showCameraView];
if(index == 3)
[self showIndoor];
if(index == 4)
[self showLocation : YES];
if(index == 5){
ZOOM_LEVEL = 10;
[self drawRoute];
}
}

-(void) showLocation : (BOOL) isCustomMarkerEnabled
{
// Create a GMSCameraPosition that tells the map to display the
// coordinate -33.86,151.20 at zoom level 6.
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.86
longitude:151.20
zoom:ZOOM_LEVEL];
mapView_ = [GMSMapView mapWithFrame:mapParentView.bounds camera:camera];
mapView_.myLocationEnabled = YES;
mapView_.delegate = self;
[mapParentView addSubview:mapView_];

[self setMarkerInMap:mapView_ inCoordinates:CLLocationCoordinate2DMake(-33.86, 151.20) withTitle:@"Sydney" snippet:@"Australia" isCustomMarker:isCustomMarkerEnabled];
}

-(void) showStreetView
{
CLLocationCoordinate2D panoramaNear = {50.059139,-122.958391};

GMSPanoramaView *panoView =
[GMSPanoramaView panoramaWithFrame:mapParentView.bounds
nearCoordinate:panoramaNear];

[mapParentView addSubview:panoView];
}

-(void) showCameraView
{
ZOOM_LEVEL = 17.5;
GMSCameraPosition *camera =
[GMSCameraPosition cameraWithLatitude:-37.809487
longitude:144.965699
zoom:ZOOM_LEVEL
bearing:30
viewingAngle:40];

mapView_ = [GMSMapView mapWithFrame:mapParentView.bounds camera:camera];
mapView_.delegate = self;
[mapParentView addSubview:mapView_];
}

-(void) showIndoor
{
ZOOM_LEVEL = 18;
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:37.78318
longitude:-122.40374
zoom:ZOOM_LEVEL];

mapView_ = [GMSMapView mapWithFrame:mapParentView.bounds camera:camera];
mapView_.delegate = self;
[mapParentView addSubview:mapView_];
}

-(void) setMarkerInMap :(GMSMapView *) mapView inCoordinates:(CLLocationCoordinate2D)coordinate withTitle:(NSString*) title snippet :(NSString *) snippet isCustomMarker :(BOOL) isCustomMarker
{
GMSCameraPosition *camera =
[GMSCameraPosition cameraWithLatitude:coordinate.latitude
longitude:coordinate.longitude
zoom:ZOOM_LEVEL];
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(coordinate.latitude, coordinate.longitude);
marker.title = title;
marker.snippet = snippet;

if(isCustomMarker){
marker.appearAnimation = kGMSMarkerAnimationPop;
marker.icon = [UIImage imageNamed:@"flag_marker"];
}
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
marker.map = mapView;
mapView.selectedMarker = marker;
[mapView animateToCameraPosition:camera];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
});
}

#pragma mark – GMSMapViewDelegate

– (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate
{
NSLog(@"You tapped at %f,%f", coordinate.latitude, coordinate.longitude);

[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

dispatch_queue_t myQueue = dispatch_queue_create("My Queue",NULL);
dispatch_async(myQueue, ^{
id handler = ^(GMSReverseGeocodeResponse *response, NSError *error) {
if (error == nil) {
GMSReverseGeocodeResult *result = response.firstResult;
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
[self setMarkerInMap:mapView inCoordinates:coordinate withTitle: result.lines[0] snippet: result.lines[1]isCustomMarker:NO];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
});

}else{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
};
geocoder_ = [GMSGeocoder new];
[geocoder_ reverseGeocodeCoordinate:coordinate completionHandler:handler];
});
}

– (void)mapView:(GMSMapView *)mapView willMove:(BOOL)gesture {
//this will clear all the markers…
//[mapView clear];
}

– (void)mapView:(GMSMapView *)mapView idleAtCameraPosition:(GMSCameraPosition *)cameraPosition {
}

– (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address
{
CLLocationCoordinate2D center;
NSString *esc_addr = [address stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSString *req = [NSString stringWithFormat:@"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%@", esc_addr];

NSData *responseData = [[NSData alloc] initWithContentsOfURL:
[NSURL URLWithString:req]]; NSError *error;
NSMutableDictionary *responseDictionary = [NSJSONSerialization
JSONObjectWithData:responseData
options:0
error:&error];
if( error )
{
NSLog(@"%@", [error localizedDescription]);
center.latitude = 0;
center.longitude = 0;
return center;
}
else {
NSArray *results = (NSArray *) responseDictionary[@"results"];
NSDictionary *firstItem = (NSDictionary *) [results objectAtIndex:0];
NSDictionary *geometry = (NSDictionary *) [firstItem objectForKey:@"geometry"];
NSDictionary *location = (NSDictionary *) [geometry objectForKey:@"location"];
NSNumber *lat = (NSNumber *) [location objectForKey:@"lat"];
NSNumber *lng = (NSNumber *) [location objectForKey:@"lng"];

center.latitude = [lat doubleValue];
center.longitude = [lng doubleValue];
return center;
}

}

-(BOOL) textFieldShouldReturn:(UITextField *) textField{
[textField resignFirstResponder];

if ([[textField text] length] > 0) {

[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

dispatch_queue_t myQueue = dispatch_queue_create("My Queue",NULL);
dispatch_async(myQueue, ^{
[self setMarkerInMap:mapView_ inCoordinates:[self geoCodeUsingAddress:textField.text] withTitle:textField.text snippet:textField.text isCustomMarker:NO];

});

}
return YES;
}

– (void)drawRoute
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
CLLocationCoordinate2D origin = CLLocationCoordinate2DMake(-33.86, 151.20);
[self setMarkerInMap:mapView_ inCoordinates:origin withTitle:@"Origin" snippet:@"Origin" isCustomMarker:NO];
CLLocationCoordinate2D destination = CLLocationCoordinate2DMake(-33.56, 151.20);
[self setMarkerInMap:mapView_ inCoordinates:destination withTitle:@"Destination" snippet:@"Destination" isCustomMarker:NO];

dispatch_queue_t myQueue = dispatch_queue_create("My Queue",NULL);
dispatch_async(myQueue, ^{

[self fetchPolylineWithOrigin:origin destination:destination completionHandler:^(GMSPolyline *polyline)
{
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
if(polyline)
polyline.map = mapView_;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
});

}];

});
}

– (void)fetchPolylineWithOrigin:(CLLocationCoordinate2D )origin destination:(CLLocationCoordinate2D )destination completionHandler:(void (^)(GMSPolyline *))completionHandler
{
NSString *originString = [NSString stringWithFormat:@"%f,%f", origin.latitude, origin.longitude];
NSString *destinationString = [NSString stringWithFormat:@"%f,%f", destination.latitude, destination.longitude];
NSString *directionsAPI = @"https://maps.googleapis.com/maps/api/directions/json?";
NSString *directionsUrlString = [NSString stringWithFormat:@"%@&origin=%@&destination=%@&mode=driving", directionsAPI, originString, destinationString];
NSURL *directionsUrl = [NSURL URLWithString:directionsUrlString];

NSURLSessionDataTask *fetchDirectionsTask = [[NSURLSession sharedSession] dataTaskWithURL:directionsUrl completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error)
{
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if(error)
{
if(completionHandler)
completionHandler(nil);
return;
}

NSArray *routesArray = [json objectForKey:@"routes"];

GMSPolyline *polyline = nil;
if ([routesArray count] > 0)
{
NSDictionary *routeDict = [routesArray objectAtIndex:0];
NSDictionary *routeOverviewPolyline = [routeDict objectForKey:@"overview_polyline"];
NSString *points = [routeOverviewPolyline objectForKey:@"points"];
GMSPath *path = [GMSPath pathFromEncodedPath:points];
polyline = [GMSPolyline polylineWithPath:path];
}

polyline.strokeWidth = 7;
polyline.strokeColor = [UIColor redColor];
if(completionHandler)
completionHandler(polyline);
}];
[fetchDirectionsTask resume];
}

@end

[/java]

I also have a image named “flag_marker” in the resources which is being used as Custom Marker.

Leave a Reply

Your email address will not be published. Required fields are marked *