Woah… long time no blogging… Busy busy busy. Quite busy lately enhancing our app, Movreak to achieve the best movie-related iPhone app yet.
So, today I delivered a sharing of introduction to iOS 7 development for Telkom Bandung Digital Valley (BDV) members and Bandung’s developers in general. The event was full house! It’s exciting to see such a great interest.
A promise I made for the event is doing a demo to access API provided by BDV-incubated startups. Since the startup I know and that provides open API is related to mapping and routing solution for public transportation in Bandung (currently), it’s best to do the map-related demo app.
One of the new feature in iOS 7 SDK is the ability to request directions from coordinate A to coordinate B, and directly draw the direction on top of MKMapView as overlay. Simply enough, to request the directions, all you have to do is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
- (void)findDirectionsFrom:(MKMapItem *)source to:(MKMapItem *)destination { //provide loading animation here MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init]; request.source = source; request.transportType = MKDirectionsTransportTypeAutomobile; request.destination = destination; MKDirections *directions = [[MKDirections alloc] initWithRequest:request]; __block typeof(self) weakSelf = self; [directions calculateDirectionsWithCompletionHandler: ^(MKDirectionsResponse *response, NSError *error) { //stop loading animation here if (error) { NSLog(@"Error is %@",error); } else { //do something about the response, like draw it on map MKRoute *route = [response.routes firstObject]; [self.mapView addOverlay:route.polyline level:MKOverlayLevelAboveRoads]; } }]; } |
Using that method, pass two MKMapItem as source and destination. To create MKMapItem from coordinate, here’s the code:
1 2 3 |
CLLocationCoordinate2D _srcCoord = CLLocationCoordinate2DMake(-6.89400,107.60473); MKPlacemark *_srcMark = [[MKPlacemark alloc] initWithCoordinate:_srcCoord addressDictionary:nil]; MKMapItem *_srcItem = [[MKMapItem alloc] initWithPlacemark:_srcMark]; |
To represent current location, it’s even as easy as:
1 |
MKMapItem *_srcItem = [MKMapItem mapItemForCurrentLocation]; |
Then, to set how MKMapView drawing the route polyline, implement this MKMapView delegate method:
1 2 3 4 5 6 |
-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{ MKPolylineRenderer *polylineRender = [[MKPolylineRenderer alloc] initWithOverlay:overlay]; polylineRender.lineWidth = 3.0f; polylineRender.strokeColor = [UIColor blueColor]; return polylineRender; } |
Use your imagination there.
Custom Routing
To provide custom routing, it involves:
- Get directions data from the related source, either via REST API or any protocol specified by API provider.
- Based on returned data, construct the array of CLLocationCoordinate2D
- Create instance of MKPolyline or the new MKGeodesicPolyline in iOS 7. Based on Apple doc, The MKGeodesicPolyline class represents a line shape that traces the shortest path along the surface of the Earth. As with regular polyline overlays, you specify a geodesic polyline using a set of end-to-end points where the first and last points are not connected to each other. When displayed on a two-dimensional map view, the line segment between any two points may appear curved.
- Add the polyline as MapView overlay
- There’s no step 5… Oh, may be you should configure how to display the polyline by implementing this MapView delegate method:
1-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
Sample code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//Assumed, _coordinates is array of NSString representing comma-separated latitude and longitude, retrieved from web service or any source. CLLocationCoordinate2D points[[_coordinates count]]; NSUInteger i = 0; for (NSString *_coordinateStr in _coordinates) { NSArray *_coordParts = [_coordinateStr componentsSeparatedByString:@","]; CLLocationCoordinate2D _coord = CLLocationCoordinate2DMake([_coordParts[0] floatValue], [_coordParts[1] floatValue]); points[i] = _coord; i++; } //Create custom polyline to draw overlay MKGeodesicPolyline *publicTransportPolyline = [MKGeodesicPolyline polylineWithCoordinates:points count:[_coordinates count]]; //Add the polyline as overlay [self.mapView addOverlay: publicTransportPolyline level:MKOverlayLevelAboveRoads]; |
Here’s the screencast of final demo app. Don’t expect too much, I only had 1 hour to code it.
Complete source code project: http://cl.ly/102s2M2H411C
You are welcome. Enjoy!
Hey, want to learn more iOS 7 development? Let’s join my company’s iOS 7 professional training. It’s indeed learning from the experienced iOS developers in the country. More info: http://dycode.co.id. Can’t wait to share with you guys.
Completely kicking. Make me thinking to move and learn about iOS programming.