react-native-google-maps-plus 1.10.1-dev.1 → 1.10.1-dev.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,8 +41,6 @@ import com.google.android.gms.maps.model.TileOverlayOptions
41
41
  import com.google.maps.android.data.kml.KmlLayer
42
42
  import com.margelo.nitro.core.Promise
43
43
  import com.rngooglemapsplus.extensions.encode
44
- import com.rngooglemapsplus.extensions.onUi
45
- import com.rngooglemapsplus.extensions.onUiSync
46
44
  import com.rngooglemapsplus.extensions.toGooglePriority
47
45
  import com.rngooglemapsplus.extensions.toLatLng
48
46
  import com.rngooglemapsplus.extensions.toLocationErrorCode
@@ -749,7 +747,7 @@ class GoogleMapsViewImpl(
749
747
  kmlLayersById[id] = layer
750
748
  layer.addLayerToMap()
751
749
  } catch (_: Exception) {
752
- // ignore
750
+ mapsLog("kml layer parse failed: id=$id")
753
751
  }
754
752
  }
755
753
 
@@ -971,5 +969,5 @@ class GoogleMapsViewImpl(
971
969
 
972
970
  override fun getInfoContents(marker: Marker): View? = null
973
971
 
974
- override fun getInfoWindow(marker: Marker): View? = markerBuilder.buildInfoWindow(marker.tagData.iconSvg)
972
+ override fun getInfoWindow(marker: Marker): View? = markerBuilder.buildInfoWindow(marker.tagData)
975
973
  }
@@ -19,7 +19,6 @@ import com.google.android.gms.location.LocationServices
19
19
  import com.google.android.gms.location.LocationSettingsRequest
20
20
  import com.google.android.gms.location.Priority
21
21
  import com.google.android.gms.maps.LocationSource
22
- import com.rngooglemapsplus.extensions.onUi
23
22
  import com.rngooglemapsplus.extensions.toLocationErrorCode
24
23
 
25
24
  private const val REQ_LOCATION_SETTINGS = 2001
@@ -5,7 +5,6 @@ import com.facebook.react.uimanager.PixelUtil.dpToPx
5
5
  import com.google.android.gms.maps.model.Circle
6
6
  import com.google.android.gms.maps.model.CircleOptions
7
7
  import com.rngooglemapsplus.extensions.centerEquals
8
- import com.rngooglemapsplus.extensions.onUi
9
8
  import com.rngooglemapsplus.extensions.toColor
10
9
  import com.rngooglemapsplus.extensions.toLatLng
11
10
 
@@ -1,4 +1,4 @@
1
- package com.rngooglemapsplus.extensions
1
+ package com.rngooglemapsplus
2
2
 
3
3
  import com.facebook.react.bridge.UiThreadUtil
4
4
  import kotlinx.coroutines.CompletableDeferred
@@ -20,3 +20,16 @@ inline fun <T> onUiSync(crossinline block: () -> T): T {
20
20
  }
21
21
  return runBlocking { result.await() }
22
22
  }
23
+
24
+ private const val MAPS_LOG_TAG = "react-native-google-maps-plus"
25
+
26
+ fun mapsLog(msg: String) {
27
+ android.util.Log.w(MAPS_LOG_TAG, msg)
28
+ }
29
+
30
+ fun mapsLog(
31
+ msg: String,
32
+ t: Throwable,
33
+ ) {
34
+ android.util.Log.w(MAPS_LOG_TAG, msg, t)
35
+ }
@@ -13,6 +13,7 @@ import android.widget.LinearLayout
13
13
  import androidx.core.graphics.createBitmap
14
14
  import com.caverock.androidsvg.SVG
15
15
  import com.caverock.androidsvg.SVGExternalFileResolver
16
+ import com.caverock.androidsvg.SVGParseException
16
17
  import com.facebook.react.uimanager.PixelUtil.dpToPx
17
18
  import com.facebook.react.uimanager.ThemedReactContext
18
19
  import com.google.android.gms.maps.model.BitmapDescriptor
@@ -24,13 +25,13 @@ import com.rngooglemapsplus.extensions.coordinatesEquals
24
25
  import com.rngooglemapsplus.extensions.infoWindowAnchorEquals
25
26
  import com.rngooglemapsplus.extensions.markerInfoWindowStyleEquals
26
27
  import com.rngooglemapsplus.extensions.markerStyleEquals
27
- import com.rngooglemapsplus.extensions.onUi
28
28
  import com.rngooglemapsplus.extensions.styleHash
29
29
  import com.rngooglemapsplus.extensions.toLatLng
30
30
  import kotlinx.coroutines.CoroutineScope
31
31
  import kotlinx.coroutines.Dispatchers
32
32
  import kotlinx.coroutines.Job
33
33
  import kotlinx.coroutines.SupervisorJob
34
+ import kotlinx.coroutines.currentCoroutineContext
34
35
  import kotlinx.coroutines.ensureActive
35
36
  import kotlinx.coroutines.launch
36
37
  import kotlinx.coroutines.withContext
@@ -38,7 +39,7 @@ import java.net.HttpURLConnection
38
39
  import java.net.URL
39
40
  import java.net.URLDecoder
40
41
  import java.util.concurrent.ConcurrentHashMap
41
- import kotlin.coroutines.coroutineContext
42
+ import kotlin.coroutines.cancellation.CancellationException
42
43
 
43
44
  class MapMarkerBuilder(
44
45
  val context: ThemedReactContext,
@@ -117,6 +118,8 @@ class MapMarkerBuilder(
117
118
 
118
119
  else -> null
119
120
  }
121
+ }.onFailure {
122
+ mapsLog("external svg resolve failed")
120
123
  }.getOrNull()
121
124
  }
122
125
 
@@ -140,7 +143,7 @@ class MapMarkerBuilder(
140
143
  try {
141
144
  return Typeface.createFromAsset(assetManager, path)
142
145
  } catch (_: Throwable) {
143
- // / ignore
146
+ mapsLog("font resolve failed: $path")
144
147
  }
145
148
  }
146
149
 
@@ -264,32 +267,40 @@ class MapMarkerBuilder(
264
267
  scope.launch {
265
268
  try {
266
269
  ensureActive()
267
- val bmp = renderBitmap(m)
270
+ val renderResult = renderBitmap(m.iconSvg, m.id)
268
271
 
269
- if (bmp == null) {
270
- withContext(Dispatchers.Main) { onReady(null) }
272
+ if (renderResult?.bitmap == null) {
273
+ withContext(Dispatchers.Main) {
274
+ ensureActive()
275
+ onReady(createFallbackDescriptor())
276
+ }
271
277
  return@launch
272
278
  }
279
+
273
280
  ensureActive()
274
- val desc = BitmapDescriptorFactory.fromBitmap(bmp)
281
+ val desc = BitmapDescriptorFactory.fromBitmap(renderResult.bitmap)
275
282
 
276
- iconCache.put(key, desc)
277
- bmp.recycle()
283
+ if (!renderResult.isFallback) {
284
+ iconCache.put(key, desc)
285
+ }
286
+ renderResult.bitmap.recycle()
278
287
 
279
288
  withContext(Dispatchers.Main) {
280
289
  ensureActive()
281
290
  onReady(desc)
282
291
  }
283
292
  } catch (_: OutOfMemoryError) {
293
+ mapsLog("markerId=${m.id} buildIconAsync out of memory")
284
294
  clearIconCache()
285
295
  withContext(Dispatchers.Main) {
286
296
  ensureActive()
287
- onReady(null)
297
+ onReady(createFallbackDescriptor())
288
298
  }
289
299
  } catch (_: Throwable) {
300
+ mapsLog("markerId=${m.id} buildIconAsync failed")
290
301
  withContext(Dispatchers.Main) {
291
302
  ensureActive()
292
- onReady(null)
303
+ onReady(createFallbackDescriptor())
293
304
  }
294
305
  } finally {
295
306
  jobsById.remove(m.id)
@@ -317,8 +328,22 @@ class MapMarkerBuilder(
317
328
  iconCache.evictAll()
318
329
  }
319
330
 
320
- fun buildInfoWindow(iconSvg: RNMarkerSvg?): ImageView? {
321
- val iconSvg = iconSvg ?: return null
331
+ fun buildInfoWindow(markerTag: MarkerTag): ImageView? {
332
+ val iconSvg = markerTag.iconSvg ?: return null
333
+
334
+ val wPx =
335
+ markerTag.iconSvg.width
336
+ .dpToPx()
337
+ .toInt()
338
+ val hPx =
339
+ markerTag.iconSvg.height
340
+ .dpToPx()
341
+ .toInt()
342
+
343
+ if (wPx <= 0 || hPx <= 0) {
344
+ mapsLog("markerId=${markerTag.id} invalid svg size")
345
+ return ImageView(context)
346
+ }
322
347
 
323
348
  val svgView =
324
349
  ImageView(context).apply {
@@ -330,40 +355,73 @@ class MapMarkerBuilder(
330
355
  }
331
356
 
332
357
  try {
333
- val svg = SVG.getFromString(iconSvg.svgString)
334
- svg.setDocumentWidth(iconSvg.width.dpToPx())
335
- svg.setDocumentHeight(iconSvg.height.dpToPx())
358
+ val svg =
359
+ SVG.getFromString(iconSvg.svgString).apply {
360
+ documentWidth = wPx.toFloat()
361
+ documentHeight = hPx.toFloat()
362
+ }
336
363
  val drawable = PictureDrawable(svg.renderToPicture())
337
364
  svgView.setImageDrawable(drawable)
338
- } catch (e: Exception) {
339
- return null
365
+ } catch (_: Exception) {
366
+ mapsLog("markerId=${markerTag.id} infoWindow: svg render failed")
367
+ return ImageView(context)
340
368
  }
341
369
 
342
370
  return svgView
343
371
  }
344
372
 
345
- private suspend fun renderBitmap(m: RNMarker): Bitmap? {
346
- m.iconSvg ?: return null
373
+ private fun createFallbackBitmap(): Bitmap =
374
+ createBitmap(1, 1, Bitmap.Config.ARGB_8888).apply {
375
+ setHasAlpha(true)
376
+ }
377
+
378
+ private fun createFallbackDescriptor(): BitmapDescriptor {
379
+ val bmp = createFallbackBitmap()
380
+ return BitmapDescriptorFactory.fromBitmap(bmp).also {
381
+ bmp.recycle()
382
+ }
383
+ }
384
+
385
+ private data class RenderBitmapResult(
386
+ val bitmap: Bitmap,
387
+ val isFallback: Boolean,
388
+ )
389
+
390
+ private suspend fun renderBitmap(
391
+ iconSvg: RNMarkerSvg,
392
+ markerId: String,
393
+ ): RenderBitmapResult? {
394
+ val wPx =
395
+ iconSvg.width
396
+ .dpToPx()
397
+ .toInt()
398
+ val hPx =
399
+ iconSvg.height
400
+ .dpToPx()
401
+ .toInt()
402
+
403
+ if (wPx <= 0 || hPx <= 0) {
404
+ mapsLog("markerId=$markerId invalid svg size")
405
+ return RenderBitmapResult(createFallbackBitmap(), true)
406
+ }
347
407
 
348
408
  var bmp: Bitmap? = null
349
409
  try {
350
- coroutineContext.ensureActive()
351
- val svg = SVG.getFromString(m.iconSvg.svgString)
352
-
353
- val wPx =
354
- m.iconSvg.width
355
- .dpToPx()
356
- .toInt()
357
- val hPx =
358
- m.iconSvg.height
359
- .dpToPx()
360
- .toInt()
361
-
362
- coroutineContext.ensureActive()
363
- svg.setDocumentWidth(wPx.toFloat())
364
- svg.setDocumentHeight(hPx.toFloat())
365
-
366
- coroutineContext.ensureActive()
410
+ val svg =
411
+ try {
412
+ SVG.getFromString(iconSvg.svgString).apply {
413
+ documentWidth = wPx.toFloat()
414
+ documentHeight = hPx.toFloat()
415
+ }
416
+ } catch (_: SVGParseException) {
417
+ mapsLog("markerId=$markerId icon: svg parse failed")
418
+ return RenderBitmapResult(createFallbackBitmap(), true)
419
+ } catch (_: IllegalArgumentException) {
420
+ mapsLog("markerId=$markerId icon: svg invalid")
421
+ return RenderBitmapResult(createFallbackBitmap(), true)
422
+ }
423
+
424
+ currentCoroutineContext().ensureActive()
367
425
  bmp =
368
426
  createBitmap(wPx, hPx, Bitmap.Config.ARGB_8888).apply {
369
427
  density = context.resources.displayMetrics.densityDpi
@@ -372,13 +430,13 @@ class MapMarkerBuilder(
372
430
  }
373
431
  }
374
432
 
375
- return bmp
376
- } catch (t: Throwable) {
377
- try {
378
- bmp?.recycle()
379
- } catch (_: Throwable) {
380
- }
381
- throw t
433
+ currentCoroutineContext().ensureActive()
434
+
435
+ return RenderBitmapResult(bmp, false)
436
+ } catch (e: Exception) {
437
+ if (e is CancellationException) throw e
438
+ bmp?.recycle()
439
+ throw e
382
440
  }
383
441
  }
384
442
  }
@@ -6,7 +6,6 @@ import com.google.android.gms.maps.model.Polygon
6
6
  import com.google.android.gms.maps.model.PolygonOptions
7
7
  import com.rngooglemapsplus.extensions.coordinatesEquals
8
8
  import com.rngooglemapsplus.extensions.holesEquals
9
- import com.rngooglemapsplus.extensions.onUi
10
9
  import com.rngooglemapsplus.extensions.toColor
11
10
  import com.rngooglemapsplus.extensions.toLatLng
12
11
  import com.rngooglemapsplus.extensions.toMapsPolygonHoles
@@ -5,7 +5,6 @@ import com.facebook.react.uimanager.PixelUtil.dpToPx
5
5
  import com.google.android.gms.maps.model.Polyline
6
6
  import com.google.android.gms.maps.model.PolylineOptions
7
7
  import com.rngooglemapsplus.extensions.coordinatesEquals
8
- import com.rngooglemapsplus.extensions.onUi
9
8
  import com.rngooglemapsplus.extensions.toColor
10
9
  import com.rngooglemapsplus.extensions.toLatLng
11
10
  import com.rngooglemapsplus.extensions.toMapJointType
@@ -25,6 +25,7 @@ class MapUrlTileOverlayBuilder {
25
25
  return try {
26
26
  URL(url)
27
27
  } catch (e: Exception) {
28
+ mapsLog("tile url invalid: $url", e)
28
29
  null
29
30
  }
30
31
  }
@@ -5,6 +5,7 @@ import android.graphics.Bitmap
5
5
  import android.util.Base64
6
6
  import android.util.Size
7
7
  import androidx.core.graphics.scale
8
+ import com.rngooglemapsplus.mapsLog
8
9
  import java.io.ByteArrayOutputStream
9
10
  import java.io.File
10
11
  import java.io.FileOutputStream
@@ -30,6 +31,7 @@ fun Bitmap.encode(
30
31
  } else {
31
32
  "data:image/$format;base64," + Base64.encodeToString(bytes, Base64.NO_WRAP)
32
33
  }
33
- } catch (_: Exception) {
34
+ } catch (e: Exception) {
35
+ mapsLog("snapshot export failed", e)
34
36
  null
35
37
  }
@@ -20,7 +20,8 @@ GMSIndoorDisplayDelegate {
20
20
  private var pendingCircles: [(id: String, circle: GMSCircle)] = []
21
21
  private var pendingHeatmaps: [(id: String, heatmap: GMUHeatmapTileLayer)] = []
22
22
  private var pendingKmlLayers: [(id: String, kmlString: String)] = []
23
- private var pendingUrlTileOverlays: [(id: String, urlTileOverlay: GMSURLTileLayer)] = []
23
+ private var pendingUrlTileOverlays:
24
+ [(id: String, urlTileOverlay: GMSURLTileLayer)] = []
24
25
 
25
26
  private var markersById: [String: GMSMarker] = [:]
26
27
  private var polylinesById: [String: GMSPolyline] = [:]
@@ -1004,11 +1005,10 @@ GMSIndoorDisplayDelegate {
1004
1005
  }
1005
1006
 
1006
1007
  func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
1007
- return markerBuilder.buildInfoWindow(iconSvg: marker.tagData.iconSvg)
1008
+ return markerBuilder.buildInfoWindow(markerTag: marker.tagData)
1008
1009
  }
1009
1010
 
1010
- func mapView(_ mapView: GMSMapView, markerInfoContents marker: GMSMarker)
1011
- -> UIView? {
1011
+ func mapView(_ mapView: GMSMapView, markerInfoContents marker: GMSMarker) -> UIView? {
1012
1012
  return nil
1013
1013
  }
1014
1014
  }
@@ -33,3 +33,17 @@ func onMain(
33
33
  }
34
34
  }
35
35
  }
36
+
37
+ @inline(__always)
38
+ func mapsLog(_ message: String) {
39
+ NSLog("[react-native-google-maps-plus] %@", message)
40
+ }
41
+
42
+ @inline(__always)
43
+ func mapsLog(_ message: String, _ error: Error) {
44
+ NSLog(
45
+ "[react-native-google-maps-plus] %@ | %@",
46
+ message,
47
+ String(describing: error)
48
+ )
49
+ }
@@ -10,6 +10,10 @@ final class MapMarkerBuilder {
10
10
  }()
11
11
  private var tasks: [String: Task<Void, Never>] = [:]
12
12
 
13
+ init() {
14
+ warmupSVGKit()
15
+ }
16
+
13
17
  func build(_ m: RNMarker, icon: UIImage?) -> GMSMarker {
14
18
  let marker = GMSMarker(
15
19
  position: m.coordinate.toCLLocationCoordinate2D()
@@ -154,7 +158,7 @@ final class MapMarkerBuilder {
154
158
  ) {
155
159
  tasks[m.id]?.cancel()
156
160
 
157
- if m.iconSvg == nil {
161
+ guard let iconSvg = m.iconSvg else {
158
162
  onReady(nil)
159
163
  return
160
164
  }
@@ -173,14 +177,24 @@ final class MapMarkerBuilder {
173
177
  Task { @MainActor in self.tasks.removeValue(forKey: m.id) }
174
178
  }
175
179
 
176
- let img = self.renderUIImage(m, scale)
177
- guard let img, !Task.isCancelled else { return }
180
+ let renderResult = self.renderUIImage(iconSvg, m.id, scale)
181
+ guard !Task.isCancelled else { return }
178
182
 
179
- self.iconCache.setObject(img, forKey: key)
183
+ guard let renderResult = renderResult else {
184
+ await MainActor.run {
185
+ guard !Task.isCancelled else { return }
186
+ onReady(self.createFallbackUIImage())
187
+ }
188
+ return
189
+ }
190
+
191
+ if !renderResult.isFallback {
192
+ self.iconCache.setObject(renderResult.image, forKey: key)
193
+ }
180
194
 
181
195
  await MainActor.run {
182
196
  guard !Task.isCancelled else { return }
183
- onReady(img)
197
+ onReady(renderResult.image)
184
198
  }
185
199
  }
186
200
 
@@ -202,27 +216,36 @@ final class MapMarkerBuilder {
202
216
  CATransaction.flush()
203
217
  }
204
218
 
205
- func buildInfoWindow(iconSvg: RNMarkerSvg?) -> UIImageView? {
206
- guard let iconSvg = iconSvg else {
219
+ func buildInfoWindow(markerTag: MarkerTag) -> UIImageView? {
220
+ guard let iconSvg = markerTag.iconSvg else {
207
221
  return nil
208
222
  }
209
223
 
224
+ let w = CGFloat(iconSvg.width)
225
+ let h = CGFloat(iconSvg.height)
226
+
227
+ if w <= 0 || h <= 0 {
228
+ mapsLog("markerId=\(markerTag.id) icon: invalid svg size")
229
+ return createFallbackImageView()
230
+ }
231
+
210
232
  guard let data = iconSvg.svgString.data(using: .utf8),
211
233
  let svgImg = SVGKImage(data: data)
212
234
  else {
213
- return nil
235
+ mapsLog("markerId=\(markerTag.id) infoWindow: svg utf8 decode failed")
236
+ return createFallbackImageView()
214
237
  }
215
238
 
216
- let size = CGSize(
217
- width: max(1, CGFloat(iconSvg.width)),
218
- height: max(1, CGFloat(iconSvg.height))
219
- )
239
+ let size = CGSize(width: w, height: h)
220
240
 
221
241
  svgImg.size = size
222
242
 
223
243
  guard let finalImage = SVGKExporterUIImage.export(asUIImage: svgImg) else {
244
+ mapsLog(
245
+ "markerId=\(markerTag.id) infoWindow: svg export to UIImage failed"
246
+ )
224
247
  svgImg.clear()
225
- return nil
248
+ return createFallbackImageView()
226
249
  }
227
250
  svgImg.clear()
228
251
 
@@ -234,21 +257,63 @@ final class MapMarkerBuilder {
234
257
  return imageView
235
258
  }
236
259
 
237
- private func renderUIImage(_ m: RNMarker, _ scale: CGFloat) -> UIImage? {
260
+ private func warmupSVGKit() {
261
+ autoreleasepool {
262
+ let emptySvg = """
263
+ <svg xmlns="http://www.w3.org/2000/svg" width="1" height="1"></svg>
264
+ """
265
+ guard let data = emptySvg.data(using: .utf8),
266
+ let svgImg = SVGKImage(data: data)
267
+ else { return }
268
+ svgImg.clear()
269
+ }
270
+ }
271
+
272
+ private func createFallbackUIImage() -> UIImage {
273
+ let size = CGSize(width: 1, height: 1)
274
+ let renderer = UIGraphicsImageRenderer(size: size)
275
+ return renderer.image { _ in }
276
+ }
277
+
278
+ private func createFallbackImageView() -> UIImageView {
279
+ let iv = UIImageView(image: createFallbackUIImage())
280
+ iv.contentMode = .scaleAspectFit
281
+ iv.backgroundColor = .clear
282
+ return iv
283
+ }
284
+
285
+ private func renderUIImage(
286
+ _ iconSvg: RNMarkerSvg,
287
+ _ markerId: String,
288
+ _ scale: CGFloat
289
+ ) -> (
290
+ image: UIImage, isFallback: Bool
291
+ )? {
292
+
293
+ let w = CGFloat(iconSvg.width)
294
+ let h = CGFloat(iconSvg.height)
295
+
296
+ if w <= 0 || h <= 0 {
297
+ mapsLog("markerId=\(markerId) icon: invalid svg size")
298
+ return (createFallbackUIImage(), true)
299
+ }
300
+
238
301
  guard
239
- let iconSvg = m.iconSvg,
240
302
  let data = iconSvg.svgString.data(using: .utf8)
241
- else { return nil }
242
- print("Is main thread:", Thread.isMainThread)
303
+ else {
304
+ mapsLog("markerId=\(markerId) icon: svg utf8 decode failed")
305
+ return (createFallbackUIImage(), true)
306
+ }
243
307
 
244
- let size = CGSize(
245
- width: max(1, CGFloat(iconSvg.width)),
246
- height: max(1, CGFloat(iconSvg.height))
247
- )
308
+ let size = CGSize(width: w, height: h)
248
309
 
249
- return autoreleasepool { () -> UIImage? in
310
+ return autoreleasepool { () -> (image: UIImage, isFallback: Bool)? in
250
311
  guard !Task.isCancelled else { return nil }
251
- guard let svgImg = SVGKImage(data: data) else { return nil }
312
+
313
+ guard let svgImg = SVGKImage(data: data) else {
314
+ mapsLog("markerId=\(markerId) icon: SVGKImage init failed")
315
+ return (createFallbackUIImage(), true)
316
+ }
252
317
 
253
318
  svgImg.size = size
254
319
 
@@ -259,8 +324,14 @@ final class MapMarkerBuilder {
259
324
 
260
325
  let uiImage = SVGKExporterUIImage.export(asUIImage: svgImg)
261
326
  svgImg.clear()
262
- return uiImage
327
+
328
+ guard !Task.isCancelled else { return nil }
329
+
330
+ if let uiImage = uiImage {
331
+ return (uiImage, false)
332
+ } else {
333
+ return (createFallbackUIImage(), true)
334
+ }
263
335
  }
264
336
  }
265
-
266
337
  }
@@ -35,6 +35,7 @@ extension UIImage {
35
35
  try imageData.write(to: fileURL)
36
36
  return fileURL.path
37
37
  } catch {
38
+ mapsLog("snapshot write failed", error)
38
39
  return nil
39
40
  }
40
41
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-google-maps-plus",
3
- "version": "1.10.1-dev.1",
3
+ "version": "1.10.1-dev.2",
4
4
  "description": "React Native wrapper for Android & iOS Google Maps SDK",
5
5
  "main": "./lib/module/index.js",
6
6
  "module": "./lib/module/index.js",