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


sudo gem install cocoapods

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

   
   cd "PATH TO YOUR PROJECT"
   

Then execute command…


touch Podfile 

This will create a PodFile in your project directory.

Now Open the PodFile


open -e Podfile

Now Enter these in your PodFile and save…


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

Now come back to terminal and execute


pod install

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.

<key>NSAppTransportSecurity</key>
<dict>
  
  <key>NSAllowsArbitraryLoads
      <true></true>
</dict>

 

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…


@import GoogleMaps;

Also


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

Now in the ViewController.h


@import GoogleMaps;

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

@end

ViewController.m

Import UIKIT also…


#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

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 *