For learning purposes I'm trying to develop an app which will show directions to a specific point on a MKMapView.
However, the DirectionsResponse gives me the following error everytime, no matter the address:
2013-12-28 17:52:23.100 routingApp[378:70b] ERROR
2013-12-28 17:52:23.102 routingApp[378:70b] Directions Not Available
I only have a View Controller with a map view and the following code:
routingAppViewController.h
@interface routingAppViewController : UIViewController
@property (strong, nonatomic) IBOutlet MKMapView *mapView;
@property (strong, nonatomic) MKPlacemark *destination;
@end
routingAppViewController.m
#import "routingAppViewController.h"
@interface routingAppViewController ()
@end
@implementation routingAppViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *Location = @"385 Mid Avenue Weston";
_mapView.showsUserLocation = YES;
[self getDirections:Location];
}
-(void)getDirections:(NSString *)address{
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:address
completionHandler:^(NSArray* placemarks, NSError* error){
// Check for returned placemarks
if (placemarks && placemarks.count > 0) {
CLPlacemark *topResult = [placemarks objectAtIndex:0];
// Create a MLPlacemark and add it to the map view
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
[self.mapView addAnnotation:placemark];
_destination = placemark;
}
}];
MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:_destination];
MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];
request.source = [MKMapItem mapItemForCurrentLocation];
request.destination = mapItem;
request.requestsAlternateRoutes = NO;
MKDirections *directions = [[MKDirections alloc] initWithRequest:request];
[directions calculateDirectionsWithCompletionHandler:
^(MKDirectionsResponse *response, NSError *error) {
if (error) {
NSLog(@"ERROR");
NSLog(@"%@",[error localizedDescription]);
} else {
[self showRoute:response];
}
}];
}
-(void)showRoute:(MKDirectionsResponse *)response
{
for (MKRoute *route in response.routes)
{
[_mapView
addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
for (MKRouteStep *step in route.steps)
{
NSLog(@"%@", step.instructions);
}
}
}
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id < MKOverlay >)overlay
{
MKPolylineRenderer *renderer =
[[MKPolylineRenderer alloc] initWithOverlay:overlay];
renderer.strokeColor = [UIColor blueColor];
renderer.lineWidth = 5.0;
return renderer;
}
The error is given in the getDirections method.
I googled it and mostly the error means that the direction service is not available for this country. However i'm using an USA address, so I can't see why it's not working.
The annotation is added correctly and my location is set to "Apple".
Help much appreciated!
The
completionHandlerblock called bygeocodeAddressStringis asynchronous.This means that the code that tries to get the directions from the current location to
_destinationruns immediately after thegeocodeAddressStringline and executes before_destinationis set.So when
mapItemis created, it is using_destinationstill set tonil(the geocoder block hasn't finished and set_destinationyet).Trying to get directions from the current location to
nilresults in the get directions error.The simplest fix is to move the code that gets the directions request inside the
completionHandlerblock ofgeocodeAddressString(right after_destinationis actually set):