(iOS) bug fix: App crashes if "bearing" property is "<null>"
MODIFY
package.json
package.json
{
"name": "cordova-plugin-googlemaps",
- "version": "2.6.2",
+ "version": "2.6.3-20190614-1928",
"description": "Google Maps native SDK for Android and iOS, and Google Maps JavaScript API v3 for browser.",
"cordova": {
"id": "cordova-plugin-googlemaps",

MODIFY
plugin.xml
plugin.xml
<?xml version='1.0' encoding='utf-8'?>
-<plugin id="cordova-plugin-googlemaps" version="2.6.2" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
+<plugin id="cordova-plugin-googlemaps" version="2.6.3-20190614-1928" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>cordova-plugin-googlemaps</name>
<js-module name="Promise" src="www/Promise.js" />
<asset src="www/promise-7.0.4.min.js.map" target="promise-7.0.4.min.js.map" />

MODIFY
src/ios/GoogleMaps/CordovaGoogleMaps.m
src/ios/GoogleMaps/CordovaGoogleMaps.m
NSDictionary *cameraOptions = [initOptions valueForKey:@"camera"];
if (cameraOptions) {
- if ([cameraOptions valueForKey:@"bearing"]) {
+ if ([cameraOptions valueForKey:@"bearing"] && [cameraOptions valueForKey:@"bearing"] != [NSNull null]) {
bearing = (int)[[cameraOptions valueForKey:@"bearing"] integerValue];
} else {
bearing = 0;
}
- if ([cameraOptions valueForKey:@"tilt"]) {
+ if ([cameraOptions valueForKey:@"tilt"] && [cameraOptions valueForKey:@"tilt"] != [NSNull null]) {
angle = [[cameraOptions valueForKey:@"tilt"] doubleValue];
} else {
angle = 0;
} else {
zoom = 0;
}
- if ([cameraOptions objectForKey:@"target"]) {
+ if ([cameraOptions objectForKey:@"target"] && [cameraOptions valueForKey:@"target"] != [NSNull null]) {
NSString *targetClsName = [[cameraOptions objectForKey:@"target"] className];
if ([targetClsName isEqualToString:@"__NSCFArray"] || [targetClsName isEqualToString:@"__NSArrayM"] ) {
//--------------------------------------------

MODIFY
src/ios/GoogleMaps/PluginCircle.m
src/ios/GoogleMaps/PluginCircle.m
dispatch_async(dispatch_get_main_queue(), ^{
GMSCircle *circle = [GMSCircle circleWithPosition:position radius:radius];
- if ([json valueForKey:@"fillColor"]) {
+ if ([json valueForKey:@"fillColor"] && [json valueForKey:@"fillColor"] != [NSNull null]) {
circle.fillColor = [[json valueForKey:@"fillColor"] parsePluginColor];
}
- if ([json valueForKey:@"strokeColor"]) {
+ if ([json valueForKey:@"strokeColor"] && [json valueForKey:@"strokeColor"] != [NSNull null]) {
circle.strokeColor = [[json valueForKey:@"strokeColor"] parsePluginColor];
}
- if ([json valueForKey:@"strokeWidth"]) {
+ if ([json valueForKey:@"strokeWidth"] && [json valueForKey:@"strokeWidth"] != [NSNull null]) {
circle.strokeWidth = [[json valueForKey:@"strokeWidth"] floatValue];
}
- if ([json valueForKey:@"zIndex"]) {
+ if ([json valueForKey:@"zIndex"] && [json valueForKey:@"zIndex"] != [NSNull null]) {
circle.zIndex = [[json valueForKey:@"zIndex"] floatValue];
}
circle.map = ((GMSMapView *)(self.mapCtrl.view));
}
BOOL isClickable = NO;
- if ([[json valueForKey:@"clickable"] boolValue]) {
+ if ([json valueForKey:@"clickable"] != [NSNull null] && [[json valueForKey:@"clickable"] boolValue]) {
isClickable = YES;
}

MODIFY
src/ios/GoogleMaps/PluginGroundOverlay.m
src/ios/GoogleMaps/PluginGroundOverlay.m
groundOverlay.title = groundOverlayId;
groundOverlay.anchor = CGPointMake(0.5f, 0.5f);
- if ([json valueForKey:@"zIndex"]) {
+ if ([json valueForKey:@"zIndex"] && [json valueForKey:@"zIndex"] != [NSNull null]) {
groundOverlay.zIndex = [[json valueForKey:@"zIndex"] floatValue];
}
- if ([json valueForKey:@"bearing"]) {
+ if ([json valueForKey:@"bearing"] && [json valueForKey:@"bearing"] != [NSNull null]) {
groundOverlay.bearing = [[json valueForKey:@"bearing"] floatValue];
}
- if ([json valueForKey:@"anchor"]) {
+ if ([json valueForKey:@"anchor"] && [json valueForKey:@"anchor"] != [NSNull null]) {
NSArray *anchor = [json valueForKey:@"anchor"];
groundOverlay.anchor = CGPointMake([[anchor objectAtIndex:0] floatValue], [[anchor objectAtIndex:1] floatValue]);
}
groundOverlay.map = self.mapCtrl.map;
}
BOOL isClickable = NO;
- if ([[json valueForKey:@"clickable"] boolValue]) {
+ if ([json valueForKey:@"clickable"] != [NSNull null] && [[json valueForKey:@"clickable"] boolValue]) {
isClickable = YES;
}
//NSString *imgId = [NSString stringWithFormat:@"groundoverlay_image_%lu", (unsigned long)groundOverlay.hash];
//[me.imgCache setObject:groundOverlay.icon forKey:imgId];
- if ([json valueForKey:@"opacity"]) {
+ if ([json valueForKey:@"opacity"] && [json valueForKey:@"opacity"] != [NSNull null]) {
CGFloat opacity = [[json valueForKey:@"opacity"] floatValue];
groundOverlay.icon = [groundOverlay.icon imageByApplyingAlpha:opacity];
}

MODIFY
src/ios/GoogleMaps/PluginMap.m
src/ios/GoogleMaps/PluginMap.m
self.mapCtrl.viewDepth = [[meta objectForKey:@"depth"] integerValue];
NSDictionary *initOptions = [command.arguments objectAtIndex:1];
- if ([initOptions valueForKey:@"camera"]) {
+ if ([initOptions valueForKey:@"camera"] && [initOptions valueForKey:@"camera"] != [NSNull null]) {
double delayInSeconds = 1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
__block double bearing;
- if ([json valueForKey:@"bearing"]) {
+ if ([json valueForKey:@"bearing"] && [json valueForKey:@"bearing"] != [NSNull null]) {
bearing = [[json valueForKey:@"bearing"] doubleValue];
} else {
bearing = self.mapCtrl.map.camera.bearing;
}
double angle;
- if ([json valueForKey:@"tilt"]) {
+ if ([json valueForKey:@"tilt"] && [json valueForKey:@"tilt"] != [NSNull null]) {
angle = [[json valueForKey:@"tilt"] doubleValue];
} else {
angle = self.mapCtrl.map.camera.viewingAngle;
}
double cameraPadding = 20;
- if ([json valueForKey:@"padding"]) {
+ if ([json valueForKey:@"padding"] && [json valueForKey:@"zoom"] != [NSNull null]) {
cameraPadding = [[json valueForKey:@"padding"] doubleValue];
}
// Redraw the map mandatory
[self.mapCtrl.map setNeedsDisplay];
- if ([initOptions valueForKey:@"camera"]) {
+ if ([initOptions valueForKey:@"camera"] && [initOptions valueForKey:@"camera"] != [NSNull null]) {
//------------------------------------------
// Case : The camera option is specified.
//------------------------------------------

MODIFY
src/ios/GoogleMaps/PluginMarker.m
src/ios/GoogleMaps/PluginMarker.m
marker.tracksViewChanges = NO;
marker.tracksInfoWindowChanges = NO;
- if ([json valueForKey:@"title"]) {
+ if ([json valueForKey:@"title"] && [json valueForKey:@"title"] != [NSNull null]) {
[marker setTitle: [json valueForKey:@"title"]];
}
- if ([json valueForKey:@"snippet"]) {
+ if ([json valueForKey:@"snippet"] && [json valueForKey:@"snippet"] != [NSNull null]) {
[marker setSnippet: [json valueForKey:@"snippet"]];
}
- if ([json valueForKey:@"draggable"]) {
+ if ([json valueForKey:@"draggable"] && [json valueForKey:@"draggable"] != [NSNull null]) {
[marker setDraggable:[[json valueForKey:@"draggable"] boolValue]];
}
- if ([json valueForKey:@"flat"]) {
+ if ([json valueForKey:@"flat"] && [json valueForKey:@"flat"] != [NSNull null]) {
[marker setFlat:[[json valueForKey:@"flat"] boolValue]];
}
- if ([json valueForKey:@"rotation"]) {
+ if ([json valueForKey:@"rotation"] && [json valueForKey:@"rotation"] != [NSNull null]) {
CLLocationDegrees degrees = [[json valueForKey:@"rotation"] doubleValue];
[marker setRotation:degrees];
}
- if ([json valueForKey:@"opacity"]) {
+ if ([json valueForKey:@"opacity"] && [json valueForKey:@"opacity"] != [NSNull null]) {
[marker setOpacity:[[json valueForKey:@"opacity"] floatValue]];
}
- if ([json valueForKey:@"zIndex"]) {
+ if ([json valueForKey:@"zIndex"] && [json valueForKey:@"zIndex"] != [NSNull null]) {
[marker setZIndex:[[json valueForKey:@"zIndex"] intValue]];
}
NSMutableDictionary *properties = [[NSMutableDictionary alloc] init];
NSString *propertyId = [NSString stringWithFormat:@"marker_property_%@", markerId];
- if ([json valueForKey:@"styles"]) {
+ if ([json valueForKey:@"styles"] && [json valueForKey:@"styles"] != [NSNull null]) {
NSDictionary *styles = [json valueForKey:@"styles"];
[properties setObject:styles forKey:@"styles"];
}
BOOL disableAutoPan = NO;
- if ([json valueForKey:@"disableAutoPan"] != nil) {
+ if ([json valueForKey:@"disableAutoPan"] != nil && [json valueForKey:@"disableAutoPan"] != [NSNull null]) {
disableAutoPan = [[json valueForKey:@"disableAutoPan"] boolValue];
}
[properties setObject:[NSNumber numberWithBool:disableAutoPan] forKey:@"disableAutoPan"];
}
// Animation
- if ([json valueForKey:@"animation"]) {
+ if ([json valueForKey:@"animation"] && [json valueForKey:@"animation"] != [NSNull null]) {
animation = [json valueForKey:@"animation"];
if (iconProperty == nil) {
iconProperty = [NSMutableDictionary dictionary];
//NSLog(@"--->animation = %@", animation);
}
- if ([json valueForKey:@"infoWindowAnchor"]) {
+ if ([json valueForKey:@"infoWindowAnchor"] && [json valueForKey:@"infoWindowAnchor"] != [NSNull null]) {
[iconProperty setObject:[json valueForKey:@"infoWindowAnchor"] forKey:@"infoWindowAnchor"];
}
if (iconProperty && ([iconProperty objectForKey:@"url"] || [iconProperty objectForKey:@"iconColor"])) {
// `animation` property
NSString *animationValue = nil;
- if ([iconProperty valueForKey:@"animation"]) {
+ if ([iconProperty valueForKey:@"animation"] && [iconProperty valueForKey:@"animation"] != [NSNull null]) {
animationValue = [iconProperty valueForKey:@"animation"];
}
__block NSString *animation = animationValue;
//--------------------------------
// the icon property is color name
//--------------------------------
- if ([iconProperty valueForKey:@"iconColor"]) {
+ if ([iconProperty valueForKey:@"iconColor"] && [iconProperty valueForKey:@"iconColor"] != [NSNull null]) {
dispatch_async(dispatch_get_main_queue(), ^{
UIColor *iconColor = [iconProperty valueForKey:@"iconColor"];
marker.icon = [GMSMarker markerImageWithColor:iconColor];
}
// `size` property
- if ([iconProperty valueForKey:@"size"]) {
+ if ([iconProperty valueForKey:@"size"] && [iconProperty valueForKey:@"size"] != [NSNull null]) {
NSDictionary *size = [iconProperty valueForKey:@"size"];
width = [[size objectForKey:@"width"] floatValue];
height = [[size objectForKey:@"height"] floatValue];
CGFloat anchorX = 0;
CGFloat anchorY = 0;
// The `anchor` property for the icon
- if ([iconProperty valueForKey:@"anchor"]) {
+ if ([iconProperty valueForKey:@"anchor"] && [iconProperty valueForKey:@"anchor"] != [NSNull null]) {
NSArray *points = [iconProperty valueForKey:@"anchor"];
anchorX = [[points objectAtIndex:0] floatValue] / image.size.width;
anchorY = [[points objectAtIndex:1] floatValue] / image.size.height;
}
// The `infoWindowAnchor` property
- if ([iconProperty valueForKey:@"infoWindowAnchor"]) {
+ if ([iconProperty valueForKey:@"infoWindowAnchor"] && [iconProperty valueForKey:@"infoWindowAnchor"] != [NSNull null]) {
NSArray *points = [iconProperty valueForKey:@"infoWindowAnchor"];
anchorX = [[points objectAtIndex:0] floatValue] / image.size.width;
anchorY = [[points objectAtIndex:1] floatValue] / image.size.height;
marker.icon = image;
// The `anchor` property for the icon
- if ([iconProperty valueForKey:@"anchor"]) {
+ if ([iconProperty valueForKey:@"anchor"] && [iconProperty valueForKey:@"anchor"] != [NSNull null]) {
NSArray *points = [iconProperty valueForKey:@"anchor"];
CGFloat anchorX = [[points objectAtIndex:0] floatValue] / image.size.width;
CGFloat anchorY = [[points objectAtIndex:1] floatValue] / image.size.height;
// The `infoWindowAnchor` property
- if ([iconProperty valueForKey:@"infoWindowAnchor"]) {
+ if ([iconProperty valueForKey:@"infoWindowAnchor"] && [iconProperty valueForKey:@"infoWindowAnchor"] != [NSNull null]) {
NSArray *points = [iconProperty valueForKey:@"infoWindowAnchor"];
CGFloat anchorX = [[points objectAtIndex:0] floatValue] / image.size.width;
CGFloat anchorY = [[points objectAtIndex:1] floatValue] / image.size.height;
CGFloat anchorX = 0;
CGFloat anchorY = 0;
// The `anchor` property for the icon
- if ([iconProperty valueForKey:@"anchor"]) {
+ if ([iconProperty valueForKey:@"anchor"] && [iconProperty valueForKey:@"anchor"] != [NSNull null]) {
NSArray *points = [iconProperty valueForKey:@"anchor"];
anchorX = [[points objectAtIndex:0] floatValue] / image.size.width;
anchorY = [[points objectAtIndex:1] floatValue] / image.size.height;
}
// The `infoWindowAnchor` property
- if ([iconProperty valueForKey:@"infoWindowAnchor"]) {
+ if ([iconProperty valueForKey:@"infoWindowAnchor"] && [iconProperty valueForKey:@"infoWindowAnchor"] != [NSNull null]) {
NSArray *points = [iconProperty valueForKey:@"infoWindowAnchor"];
anchorX = [[points objectAtIndex:0] floatValue] / image.size.width;
anchorY = [[points objectAtIndex:1] floatValue] / image.size.height;
marker.icon = image;
// The `anchor` property for the icon
- if ([iconProperty valueForKey:@"anchor"]) {
+ if ([iconProperty valueForKey:@"anchor"] && [iconProperty valueForKey:@"anchor"] != [NSNull null]) {
NSArray *points = [iconProperty valueForKey:@"anchor"];
CGFloat anchorX = [[points objectAtIndex:0] floatValue] / image.size.width;
CGFloat anchorY = [[points objectAtIndex:1] floatValue] / image.size.height;
// The `infoWindowAnchor` property
- if ([iconProperty valueForKey:@"infoWindowAnchor"]) {
+ if ([iconProperty valueForKey:@"infoWindowAnchor"] && [iconProperty valueForKey:@"infoWindowAnchor"] != [NSNull null]) {
NSArray *points = [iconProperty valueForKey:@"infoWindowAnchor"];
CGFloat anchorX = [[points objectAtIndex:0] floatValue] / image.size.width;
CGFloat anchorY = [[points objectAtIndex:1] floatValue] / image.size.height;

MODIFY
src/ios/GoogleMaps/PluginPolygon.m
src/ios/GoogleMaps/PluginPolygon.m
// Create paths of the hole property if specified.
NSMutableArray *holePaths = [NSMutableArray array];
- if ([json valueForKey:@"holes"]) {
+ if ([json valueForKey:@"holes"] && [json valueForKey:@"holes"] != [NSNull null]) {
NSArray *holes = [json objectForKey:@"holes"];
NSArray *latLngArray;
NSDictionary *latLng;

MODIFY
src/ios/GoogleMaps/PluginStreetViewPanorama.m
src/ios/GoogleMaps/PluginStreetViewPanorama.m
}
- (void)_setPosition:(NSDictionary *)cameraOpts {
- if ([cameraOpts valueForKey:@"target"]) {
+ if ([cameraOpts valueForKey:@"target"] && [cameraOpts valueForKey:@"target"] != [NSNull null]) {
NSObject *target = [cameraOpts objectForKey:@"target"];
if ([target isKindOfClass:NSString.class]) {
[self.panoramaCtrl.panoramaView moveToPanoramaID:(NSString *)target];
double longitude = [[latLng valueForKey:@"lng"] doubleValue];
CLLocationCoordinate2D location = CLLocationCoordinate2DMake(latitude, longitude);
- if ([cameraOpts objectForKey:@"source"]) {
+ if ([cameraOpts objectForKey:@"source"] && [cameraOpts valueForKey:@"source"] != [NSNull null]) {
GMSPanoramaSource source = [@"OUTDOOR" isEqualToString:[cameraOpts objectForKey:@"source"]] ?
kGMSPanoramaSourceOutside : kGMSPanoramaSourceDefault;
if ([cameraOpts objectForKey:@"radius"]) {
double bearing = self.panoramaCtrl.panoramaView.camera.orientation.heading;
- if ([cameraOpts valueForKey:@"bearing"]) {
+ if ([cameraOpts valueForKey:@"bearing"] && [cameraOpts valueForKey:@"bearing"] != [NSNull null]) {
bearing = [[cameraOpts valueForKey:@"bearing"] doubleValue];
}
double angle = self.panoramaCtrl.panoramaView.camera.orientation.pitch;
- if ([cameraOpts valueForKey:@"tilt"]) {
+ if ([cameraOpts valueForKey:@"tilt"] && [cameraOpts valueForKey:@"tilt"] != [NSNull null]) {
angle = [[cameraOpts valueForKey:@"tilt"] doubleValue];
}
float zoom = self.panoramaCtrl.panoramaView.camera.zoom;
- if ([cameraOpts valueForKey:@"zoom"]) {
+ if ([cameraOpts valueForKey:@"zoom"] && [cameraOpts valueForKey:@"zoom"] != [NSNull null]) {
zoom = [[cameraOpts valueForKey:@"zoom"] doubleValue];
}

MODIFY
src/ios/GoogleMaps/PluginTileOverlay.m
src/ios/GoogleMaps/PluginTileOverlay.m
// true or default
layer.map = self.mapCtrl.map;
}
- if ([json valueForKey:@"zIndex"]) {
+ if ([json valueForKey:@"zIndex"] && [json valueForKey:@"zIndex"] != [NSNull null]) {
layer.zIndex = [[json valueForKey:@"zIndex"] floatValue];
}
- if ([json valueForKey:@"tileSize"]) {
+ if ([json valueForKey:@"tileSize"] && [json valueForKey:@"tileSize"] != [NSNull null]) {
layer.tileSize = [[json valueForKey:@"tileSize"] integerValue];
}
- if ([json valueForKey:@"opacity"]) {
+ if ([json valueForKey:@"opacity"] && [json valueForKey:@"opacity"] != [NSNull null]) {
layer.opacity = [[json valueForKey:@"opacity"] floatValue];
}

(iOS) bug fix: App crashes if "bearing" property is "<null>" #2644