I know this question is more than 1 year old but I couldn't find any solution, so I hope my solution will be useful.
You can load KML into GMSMapView using iOS-KML-Framework. I've ported this code from a project that was using KML-Viewer
Add method for parsing KML from the given URL, make sure you pass correct app bundle to dispatch_queue_create():
- (void)loadKMLAtURL:(NSURL *)url
{
dispatch_queue_t loadKmlQueue = dispatch_queue_create("com.example.app.kmlqueue", NULL);
dispatch_async(loadKmlQueue, ^{
KMLRoot *newKml = [KMLParser parseKMLAtURL:url];
[self performSelectorOnMainThread:@selector(kmlLoaded:) withObject:newKml waitUntilDone:YES];
});
}
Handle the KML parsing result or error:
- (void)kmlLoaded:(id)sender {
self.navigationController.view.userInteractionEnabled = NO;
__kml = sender;
// remove KML format error observer
[[NSNotificationCenter defaultCenter] removeObserver:self name:kKMLInvalidKMLFormatNotification object:nil];
if (__kml) {
__geometries = __kml.geometries;
dispatch_async(dispatch_get_main_queue(), ^{
self.navigationController.view.userInteractionEnabled = YES;
[self reloadMapView];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
self.navigationController.view.userInteractionEnabled = YES;
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil)
message:NSLocalizedString(@"Failed to read the KML file", nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles:nil];
[alertView show];
});
}
}
Go over the geometry items from KML and add them to the GMSMapView as markers:
- (void)reloadMapView
{
NSMutableArray *annotations = [NSMutableArray array];
for (KMLAbstractGeometry *geometry in __geometries) {
MKShape *mkShape = [geometry mapkitShape];
if (mkShape) {
if ([mkShape isKindOfClass:[MKPointAnnotation class]]) {
MKPointAnnotation *annotation = (MKPointAnnotation*)mkShape;
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = annotation.coordinate;
marker.appearAnimation = kGMSMarkerAnimationPop;
marker.icon = [UIImage imageNamed:@"marker"];
marker.title = annotation.title;
marker.userData = [NSString stringWithFormat:@"%@", geometry.placemark.descriptionValue];
marker.map = self.mapView;
[annotations addObject:annotation];
}
}
}
// set bounds in next run loop.
dispatch_async(dispatch_get_main_queue(), ^{
GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] init];
for (id <MKAnnotation> annotation in annotations)
{
bounds = [bounds includingCoordinate:annotation.coordinate];
}
GMSCameraUpdate *update = [GMSCameraUpdate fitBounds:bounds];
[self.mapView moveCamera:update];
[self.mapView animateToViewingAngle:50];
});
}
At the end of the last method we're updating the camera view to fit all the markers that were added to the map. You can remove this part if it's not needed.