Objective-C - draw line in App with Google map & googleAPI(Direction)

Firstable, we need to get a Google API key

then, build a response model for it,

call direction API, get the result in App and do the transfer from JSON to our result model.

finally, use polylines from the result to draw it on mapview, done!

1. Model

// PLGoogleDirection.h

@interface PLGoogleDirection : PLAPIClass
@property (nonatomic,strong) NSString* distanceText;
@property (nonatomic,strong) NSNumber* distanceValue;
@property (nonatomic,strong) NSString* durationText;
@property (nonatomic,strong) NSNumber* durationValue;
@property (nonatomic,strong) NSString* start_address;
@property (nonatomic,strong) NSString* end_address;
@property (strong,nonatomic) NSMutableArray* poly_lines;
@end

// PLGoogleDirection.m
@implementation PLGoogleDirection
-(id)initWithDictionary:(NSDictionary*)dic{
    self = [super init];
    if (self) {
        NSArray* routes = [[NSArray alloc] initWithObjects:dic[@"routes"], nil];
        if (nil != routes[0]) {
            NSDictionary* route = routes[0][0];
            NSArray* legs = [[NSArray alloc] initWithObjects:route[@"legs"], nil];
            if (nil != legs[0]) {
                NSDictionary* leg = legs[0][0];
                NSDictionary* distance = leg[@"distance"];
                NSDictionary* duration = leg[@"duration"];
                self.distanceText = distance[@"text"];
                self.distanceValue = distance[@"value"];
                self.durationText = duration[@"text"];
                self.durationValue = duration[@"value"];
                self.end_address = leg[@"end_address"];
                self.start_address = leg[@"start_address"];
                self.poly_lines = [NSMutableArray array];
                NSArray* step =[NSArray arrayWithObject:leg[@"steps"]];// [[NSArray alloc] initWithObjects:leg[@"steps"], nil ];
                NSArray* steps = [NSArray arrayWithArray:step[0]];
                for (int iIndex = 0;iIndex < steps.count; iIndex++) {
                    NSDictionary* route = steps[iIndex];
                    [self.poly_lines addObject:route[@"polyline"][@"points"]];
                }
            }
        }

    }
    return self;
}
@end

2. draw the lines

// My ViewController.m
// keep the line for clear it every time when u draw.
@property (strong, nonatomic) NSMutableArray<GMSPolyline*>*             onMapNavigationLines;

-(void) viewDidLoad {
... your code

self.onMapNavigationLines = [NSMutableArray array]; // init array

... your code
}


-(void) showPathWith:(NSArray *)polyStrs {
    for (NSString* polyStr in polyStrs) {
        GMSPath *path = [GMSPath pathFromEncodedPath:polyStr];
        GMSPolyline *polyline = [GMSPolyline polylineWithPath:path];
        polyline.strokeWidth = 3.0;
        polyline.strokeColor = [UIColor redColor];
        polyline.map = self.mapView;
        [self.onMapNavigationLines addObject:polyline];
    }
}

-(void) clearOnMapNavigationPath {
    for (GMSPolyline* polyline in self.onMapNavigationLines) {
        polyline.map = nil;
    }
    
}

3. Clear old line and draw the new line

- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {
...  your code
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            [self getNaviationRoutes:self.mapView.myLocation destincation:[[CLLocation alloc] initWithLatitude:marker.position.latitude longitude:marker.position.longitude ]];

        });

... your code
}


-(void) getNaviationRoutes:(CLLocation*) from destincation:(CLLocation*) destination {
    [PLGoogleAPI getGoogleDirectionWithFrom:from Destination:destination
                                    success:^(NSURLSessionDataTask *task, PLGoogleDirection* googleDirection) {
                                        if (nil != googleDirection) {
                                            if (nil != googleDirection.poly_lines) {
                                                [self clearOnMapNavigationPath];
                                                [self showPathWith:googleDirection.poly_lines];
                                            }
                                        }
                                    } failure:^(NSURLSessionDataTask *task, NSError *error) {
                                        [UIAlertController presentErrorAlertControllerWithPresent:self
                                                                                presentCompletion:nil
                                                                                            error:error
                                                                                    cancelHandler:nil];
                                    }];
    
}