expo-gaode-map 2.2.38 → 2.2.39

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.
Files changed (79) hide show
  1. package/android/build.gradle +6 -31
  2. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +35 -12
  3. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapViewModule.kt +2 -0
  4. package/android/src/main/java/expo/modules/gaodemap/managers/UIManager.kt +8 -0
  5. package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +48 -7
  6. package/build/ExpoGaodeMapOfflineModule.js +1 -1
  7. package/build/ExpoGaodeMapOfflineModule.js.map +1 -1
  8. package/build/ExpoGaodeMapView.js +2 -8
  9. package/build/ExpoGaodeMapView.js.map +1 -1
  10. package/build/components/AreaMaskOverlay.d.ts +1 -2
  11. package/build/components/AreaMaskOverlay.d.ts.map +1 -1
  12. package/build/components/AreaMaskOverlay.js +2 -1
  13. package/build/components/AreaMaskOverlay.js.map +1 -1
  14. package/build/components/FoldableMapView.d.ts +3 -2
  15. package/build/components/FoldableMapView.d.ts.map +1 -1
  16. package/build/components/FoldableMapView.js +2 -1
  17. package/build/components/FoldableMapView.js.map +1 -1
  18. package/build/components/MapUI.js +2 -1
  19. package/build/components/MapUI.js.map +1 -1
  20. package/build/components/RouteOverlay.d.ts +1 -2
  21. package/build/components/RouteOverlay.d.ts.map +1 -1
  22. package/build/components/RouteOverlay.js +5 -5
  23. package/build/components/RouteOverlay.js.map +1 -1
  24. package/build/components/overlays/Circle.d.ts +1 -1
  25. package/build/components/overlays/Circle.d.ts.map +1 -1
  26. package/build/components/overlays/Circle.js +2 -1
  27. package/build/components/overlays/Circle.js.map +1 -1
  28. package/build/components/overlays/Cluster.d.ts +1 -1
  29. package/build/components/overlays/Cluster.d.ts.map +1 -1
  30. package/build/components/overlays/Cluster.js +2 -1
  31. package/build/components/overlays/Cluster.js.map +1 -1
  32. package/build/components/overlays/HeatMap.d.ts +1 -1
  33. package/build/components/overlays/HeatMap.d.ts.map +1 -1
  34. package/build/components/overlays/HeatMap.js +2 -1
  35. package/build/components/overlays/HeatMap.js.map +1 -1
  36. package/build/components/overlays/Marker.d.ts +1 -1
  37. package/build/components/overlays/Marker.d.ts.map +1 -1
  38. package/build/components/overlays/Marker.js +8 -7
  39. package/build/components/overlays/Marker.js.map +1 -1
  40. package/build/components/overlays/MultiPoint.d.ts +1 -2
  41. package/build/components/overlays/MultiPoint.d.ts.map +1 -1
  42. package/build/components/overlays/MultiPoint.js +2 -1
  43. package/build/components/overlays/MultiPoint.js.map +1 -1
  44. package/build/components/overlays/Polygon.d.ts +1 -1
  45. package/build/components/overlays/Polygon.d.ts.map +1 -1
  46. package/build/components/overlays/Polygon.js +2 -1
  47. package/build/components/overlays/Polygon.js.map +1 -1
  48. package/build/components/overlays/Polyline.d.ts +1 -1
  49. package/build/components/overlays/Polyline.d.ts.map +1 -1
  50. package/build/components/overlays/Polyline.js +2 -1
  51. package/build/components/overlays/Polyline.js.map +1 -1
  52. package/build/module/geometry.d.ts.map +1 -1
  53. package/build/module/geometry.js +2 -1
  54. package/build/module/geometry.js.map +1 -1
  55. package/build/search/ExpoGaodeMapSearchModule.d.ts +1 -1
  56. package/build/search/ExpoGaodeMapSearchModule.d.ts.map +1 -1
  57. package/build/search/ExpoGaodeMapSearchModule.js.map +1 -1
  58. package/build/types/common.types.d.ts +1 -1
  59. package/build/types/common.types.d.ts.map +1 -1
  60. package/build/types/common.types.js.map +1 -1
  61. package/build/types/index.d.ts +1 -1
  62. package/build/types/index.d.ts.map +1 -1
  63. package/build/types/index.js.map +1 -1
  64. package/build/types/map-view.types.d.ts +13 -2
  65. package/build/types/map-view.types.d.ts.map +1 -1
  66. package/build/types/map-view.types.js.map +1 -1
  67. package/build/utils/GeoUtils.d.ts +2 -2
  68. package/build/utils/GeoUtils.d.ts.map +1 -1
  69. package/build/utils/GeoUtils.js +3 -3
  70. package/build/utils/GeoUtils.js.map +1 -1
  71. package/build/utils/RouteUtils.d.ts.map +1 -1
  72. package/build/utils/RouteUtils.js +5 -2
  73. package/build/utils/RouteUtils.js.map +1 -1
  74. package/ios/ExpoGaodeMapView.swift +281 -15
  75. package/ios/ExpoGaodeMapViewModule.swift +5 -0
  76. package/ios/managers/UIManager.swift +3 -0
  77. package/ios/overlays/MarkerView.swift +205 -38
  78. package/package.json +9 -7
  79. package/plugin/build/withGaodeMap.js +3 -2
@@ -75,8 +75,16 @@ class MarkerView: ExpoView {
75
75
  private var pendingUpdateTask: DispatchWorkItem?
76
76
  /// 子视图变化后的延迟刷新任务
77
77
  private var pendingSubviewRefreshTask: DispatchWorkItem?
78
+ /// cacheKey 变化后的延迟刷新任务
79
+ private var pendingCacheKeyRefreshTask: DispatchWorkItem?
80
+ /// 视图 detach 后延迟确认移除 annotation,避免 React 更新时短暂 detach 导致闪烁
81
+ private var pendingAnnotationRemovalTask: DispatchWorkItem?
82
+ /// cacheKey 刷新代次,用于丢弃过期截图任务
83
+ private var cacheKeyRefreshGeneration: Int = 0
78
84
  /// 最近一次应用到 annotationView 的 children 结构签名
79
85
  private var lastRenderedChildrenSignature: String?
86
+ /// 最近一次成功渲染的 children 图片,用于缓存未命中时避免闪烁
87
+ private var lastRenderedChildrenImage: UIImage?
80
88
  /// 上次设置的地图引用(防止重复调用)
81
89
  private weak var lastSetMapView: MAMapView?
82
90
 
@@ -156,7 +164,11 @@ class MarkerView: ExpoView {
156
164
  func setCacheKey(_ key: String?) {
157
165
  guard cacheKey != key else { return }
158
166
  self.cacheKey = key
159
- refreshAnnotationAppearance(invalidateChildrenCache: !subviews.isEmpty)
167
+ if !subviews.isEmpty {
168
+ scheduleCacheKeyChildrenImageRefresh()
169
+ } else {
170
+ refreshAnnotationAppearance()
171
+ }
160
172
  }
161
173
 
162
174
  /**
@@ -233,9 +245,8 @@ class MarkerView: ExpoView {
233
245
  let size = resolvedContentSubviewSize(defaultSize: CGSize(width: 200, height: 60))
234
246
  let key = childrenCacheKey(for: size)
235
247
  if let cached = IconBitmapCache.shared.image(forKey: key) {
236
- annotationView?.image = cached
237
248
  if let annotationView = annotationView {
238
- applyCenterOffset(to: annotationView, defaultOffset: .zero)
249
+ applyChildrenImage(cached, to: annotationView, signature: childrenRenderSignature())
239
250
  }
240
251
  return annotationView
241
252
  }
@@ -244,9 +255,8 @@ class MarkerView: ExpoView {
244
255
  DispatchQueue.main.async { [weak self, weak annotationView] in
245
256
  guard let self = self, let annotationView = annotationView else { return }
246
257
  guard self.isAnnotationView(annotationView, boundTo: annotation) else { return }
247
- if let generated = self.createImageFromSubviews() {
248
- annotationView.image = generated
249
- self.applyCenterOffset(to: annotationView, defaultOffset: .zero)
258
+ if let generated = self.createImageFromSubviews(size: size) {
259
+ self.applyChildrenImage(generated, to: annotationView, signature: self.childrenRenderSignature())
250
260
  }
251
261
  }
252
262
  return annotationView
@@ -307,9 +317,7 @@ class MarkerView: ExpoView {
307
317
 
308
318
  // 🔑 如果有 children,使用自定义视图
309
319
  if self.subviews.count > 0 {
310
- let reuseToken = cacheKey?.replacingOccurrences(of: "|", with: "_")
311
- ?? String(ObjectIdentifier(self).hashValue)
312
- let reuseId = "custom_marker_children_\(reuseToken)" + (growAnimation ? "_grow" : "")
320
+ let reuseId = "custom_marker_children_\(ObjectIdentifier(self).hashValue)" + (growAnimation ? "_grow" : "")
313
321
  var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
314
322
  if annotationView == nil {
315
323
  if growAnimation {
@@ -331,37 +339,44 @@ class MarkerView: ExpoView {
331
339
  // 生成 cacheKey 或 fallback 到 identifier
332
340
  let size = resolvedContentSubviewSize(defaultSize: CGSize(width: 200, height: 40))
333
341
  let key = childrenCacheKey(for: size)
342
+ let signature = childrenRenderSignature()
334
343
 
335
344
  // 1) 如果缓存命中,直接同步返回图像(fast path)
336
345
  if let cached = IconBitmapCache.shared.image(forKey: key) {
337
- annotationView?.image = cached
338
346
  if let annotationView = annotationView {
339
- applyCenterOffset(to: annotationView, defaultOffset: .zero)
347
+ applyChildrenImage(cached, to: annotationView, signature: signature)
340
348
  }
341
349
  return annotationView
342
350
  }
343
351
 
344
- // 2) 缓存未命中:返回占位(透明),并异步在主线程生成图像然后回填
345
- UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
346
- let transparentImage = UIGraphicsGetImageFromCurrentImageContext()
347
- UIGraphicsEndImageContext()
348
- annotationView?.image = transparentImage
352
+ // 2) 缓存未命中:先尝试同步渲染,失败时保留旧图,避免点击切态闪烁。
353
+ if let generated = createImageFromSubviews(size: size) {
354
+ if let annotationView = annotationView {
355
+ applyChildrenImage(generated, to: annotationView, signature: signature)
356
+ }
357
+ return annotationView
358
+ }
349
359
 
350
- // 🔑 修复:延长延迟时间,给 React Native Image 更多加载时间
360
+ if annotationView?.image == nil, let previousImage = lastRenderedChildrenImage {
361
+ annotationView?.image = previousImage
362
+ if let annotationView = annotationView {
363
+ applyCenterOffset(to: annotationView, defaultOffset: .zero)
364
+ }
365
+ }
366
+
367
+ // 图片内容可能尚未就绪,保留旧图并延迟重试,避免透明闪烁。
351
368
  DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self, weak annotationView] in
352
369
  guard let self = self, let annotationView = annotationView else { return }
353
370
  guard self.isAnnotationView(annotationView, boundTo: annotation) else { return }
354
371
  // 再次检查缓存(避免重复渲染)
355
372
  if let cached = IconBitmapCache.shared.image(forKey: key) {
356
- annotationView.image = cached
357
- self.applyCenterOffset(to: annotationView, defaultOffset: .zero)
373
+ self.applyChildrenImage(cached, to: annotationView, signature: signature)
358
374
  return
359
375
  }
360
376
 
361
377
  // 调用你的原生渲染逻辑(保留空白检测、多次 layout)
362
- if let generated = self.createImageFromSubviews() {
363
- annotationView.image = generated
364
- self.applyCenterOffset(to: annotationView, defaultOffset: .zero)
378
+ if let generated = self.createImageFromSubviews(size: size) {
379
+ self.applyChildrenImage(generated, to: annotationView, signature: signature)
365
380
  } else if self.hasPendingImageContent() {
366
381
  self.scheduleSubviewRefresh(allowFallbackToDefault: false)
367
382
  }
@@ -499,11 +514,11 @@ class MarkerView: ExpoView {
499
514
  /**
500
515
  * 将子视图转换为图片
501
516
  */
502
- private func createImageFromSubviews() -> UIImage? {
503
- let size = resolvedContentSubviewSize(defaultSize: CGSize(width: 200, height: 60))
517
+ private func createImageFromSubviews(size explicitSize: CGSize? = nil, cacheImage: Bool = true) -> UIImage? {
518
+ let size = explicitSize ?? resolvedContentSubviewSize(defaultSize: CGSize(width: 200, height: 60))
504
519
  let key = childrenCacheKey(for: size)
505
520
 
506
- if let cachedImage = IconBitmapCache.shared.image(forKey: key) {
521
+ if cacheImage, let cachedImage = IconBitmapCache.shared.image(forKey: key) {
507
522
  return cachedImage
508
523
  }
509
524
 
@@ -544,11 +559,133 @@ class MarkerView: ExpoView {
544
559
 
545
560
 
546
561
 
547
- IconBitmapCache.shared.setImage(image, forKey: key)
562
+ if cacheImage {
563
+ IconBitmapCache.shared.setImage(image, forKey: key)
564
+ }
548
565
 
549
566
  return image
550
567
  }
551
568
 
569
+ private func applyChildrenImage(_ image: UIImage, to annotationView: MAAnnotationView, signature: String? = nil) {
570
+ annotationView.image = image
571
+ applyCenterOffset(to: annotationView, defaultOffset: .zero)
572
+ annotationView.canShowCallout = false
573
+ annotationView.isDraggable = draggable
574
+ lastRenderedChildrenImage = image
575
+ if let resolvedSignature = signature {
576
+ lastRenderedChildrenSignature = resolvedSignature
577
+ }
578
+ }
579
+
580
+ private func currentChildrenAnnotationView() -> MAAnnotationView? {
581
+ if let annotationView,
582
+ let annotation,
583
+ isAnnotationView(annotationView, boundTo: annotation) {
584
+ return annotationView
585
+ }
586
+
587
+ if annotationView != nil {
588
+ annotationView = nil
589
+ }
590
+
591
+ if let animatedAnnotationView,
592
+ let animatedAnnotation,
593
+ isAnnotationView(animatedAnnotationView, boundTo: animatedAnnotation) {
594
+ return animatedAnnotationView
595
+ }
596
+
597
+ if animatedAnnotationView != nil {
598
+ animatedAnnotationView = nil
599
+ }
600
+
601
+ return nil
602
+ }
603
+
604
+ private func refreshChildrenImageInPlace(invalidateChildrenCache: Bool = false, cacheImage: Bool = true) {
605
+ guard !isRemoving else { return }
606
+
607
+ let refresh = { [weak self] in
608
+ guard let self = self, !self.isRemoving, !self.subviews.isEmpty else { return }
609
+
610
+ if invalidateChildrenCache {
611
+ self.lastRenderedChildrenSignature = nil
612
+ self.invalidateCurrentChildrenCache()
613
+ }
614
+
615
+ guard let targetView = self.currentChildrenAnnotationView() else {
616
+ self.refreshAnnotationAppearance(invalidateChildrenCache: invalidateChildrenCache)
617
+ return
618
+ }
619
+
620
+ let size = self.resolvedContentSubviewSize(defaultSize: CGSize(width: 200, height: 40))
621
+ let key = self.childrenCacheKey(for: size)
622
+ let signature = self.childrenRenderSignature()
623
+
624
+ if cacheImage, let cached = IconBitmapCache.shared.image(forKey: key) {
625
+ self.applyChildrenImage(cached, to: targetView, signature: signature)
626
+ return
627
+ }
628
+
629
+ if let generated = self.createImageFromSubviews(size: size, cacheImage: cacheImage) {
630
+ self.applyChildrenImage(generated, to: targetView, signature: signature)
631
+ return
632
+ }
633
+
634
+ if self.hasPendingImageContent() {
635
+ self.scheduleSubviewRefresh(allowFallbackToDefault: false)
636
+ }
637
+ }
638
+
639
+ if Thread.isMainThread {
640
+ refresh()
641
+ } else {
642
+ DispatchQueue.main.async(execute: refresh)
643
+ }
644
+ }
645
+
646
+ private func scheduleChildrenImageRefresh(
647
+ invalidateChildrenCache: Bool = false,
648
+ cacheImage: Bool = true,
649
+ delay: TimeInterval = 0.02
650
+ ) {
651
+ pendingSubviewRefreshTask?.cancel()
652
+
653
+ let task = DispatchWorkItem { [weak self] in
654
+ self?.refreshChildrenImageInPlace(invalidateChildrenCache: invalidateChildrenCache, cacheImage: cacheImage)
655
+ }
656
+
657
+ pendingSubviewRefreshTask = task
658
+ DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: task)
659
+ }
660
+
661
+ private func scheduleCacheKeyChildrenImageRefresh() {
662
+ pendingSubviewRefreshTask?.cancel()
663
+ pendingSubviewRefreshTask = nil
664
+ pendingCacheKeyRefreshTask?.cancel()
665
+
666
+ cacheKeyRefreshGeneration += 1
667
+ let generation = cacheKeyRefreshGeneration
668
+
669
+ lastRenderedChildrenSignature = nil
670
+ invalidateCurrentChildrenCache()
671
+
672
+ let uncachedTask = DispatchWorkItem { [weak self] in
673
+ guard let self = self, !self.isRemoving, self.cacheKeyRefreshGeneration == generation else { return }
674
+ self.refreshChildrenImageInPlace(invalidateChildrenCache: true, cacheImage: false)
675
+
676
+ let cachedTask = DispatchWorkItem { [weak self] in
677
+ guard let self = self, !self.isRemoving, self.cacheKeyRefreshGeneration == generation else { return }
678
+ self.refreshChildrenImageInPlace(invalidateChildrenCache: true, cacheImage: true)
679
+ }
680
+
681
+ self.pendingCacheKeyRefreshTask = cachedTask
682
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.08, execute: cachedTask)
683
+ }
684
+
685
+ pendingCacheKeyRefreshTask = uncachedTask
686
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.02, execute: uncachedTask)
687
+ }
688
+
552
689
  private func iconCacheKey(for iconUri: String) -> String {
553
690
  let baseKey = cacheKey ?? "icon|\(iconUri)"
554
691
  return "\(baseKey)|\(Int(iconWidth.rounded()))x\(Int(iconHeight.rounded()))"
@@ -719,12 +856,39 @@ class MarkerView: ExpoView {
719
856
  */
720
857
  override func willMove(toSuperview newSuperview: UIView?) {
721
858
  super.willMove(toSuperview: newSuperview)
722
-
723
- // 如果 newSuperview 为 nil,说明视图正在被移除
859
+
724
860
  if newSuperview == nil {
725
- removeAnnotationFromMap()
861
+ scheduleAnnotationRemovalFromMap()
862
+ } else {
863
+ cancelPendingAnnotationRemoval()
726
864
  }
727
865
  }
866
+
867
+ override func didMoveToSuperview() {
868
+ super.didMoveToSuperview()
869
+
870
+ if superview != nil {
871
+ cancelPendingAnnotationRemoval()
872
+ }
873
+ }
874
+
875
+ private func scheduleAnnotationRemovalFromMap() {
876
+ cancelPendingAnnotationRemoval()
877
+
878
+ let task = DispatchWorkItem { [weak self] in
879
+ guard let self = self, self.superview == nil else { return }
880
+ self.pendingAnnotationRemovalTask = nil
881
+ self.removeAnnotationFromMap()
882
+ }
883
+
884
+ pendingAnnotationRemovalTask = task
885
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: task)
886
+ }
887
+
888
+ private func cancelPendingAnnotationRemoval() {
889
+ pendingAnnotationRemovalTask?.cancel()
890
+ pendingAnnotationRemovalTask = nil
891
+ }
728
892
 
729
893
  /**
730
894
  * 从地图移除标记点
@@ -732,9 +896,11 @@ class MarkerView: ExpoView {
732
896
  private func removeAnnotationFromMap() {
733
897
  guard !isRemoving else { return }
734
898
  isRemoving = true
899
+ cancelPendingAnnotationRemoval()
735
900
  pendingAddTask?.cancel(); pendingAddTask = nil
736
901
  pendingUpdateTask?.cancel(); pendingUpdateTask = nil
737
902
  pendingSubviewRefreshTask?.cancel(); pendingSubviewRefreshTask = nil
903
+ pendingCacheKeyRefreshTask?.cancel(); pendingCacheKeyRefreshTask = nil
738
904
 
739
905
  if Thread.isMainThread {
740
906
  cleanupAnnotationFromMap()
@@ -769,6 +935,8 @@ class MarkerView: ExpoView {
769
935
  animatedAnnotationView?.annotation = nil
770
936
  annotationView = nil
771
937
  animatedAnnotationView = nil
938
+ lastRenderedChildrenImage = nil
939
+ lastRenderedChildrenSignature = nil
772
940
  isAnimating = false
773
941
  lastSetMapView = nil
774
942
  self.mapView = nil
@@ -844,18 +1012,15 @@ class MarkerView: ExpoView {
844
1012
  return
845
1013
  }
846
1014
 
847
- guard let annotationView = annotationView else {
1015
+ guard let annotationView = currentChildrenAnnotationView() else {
848
1016
  mapView.removeAnnotation(annotation)
849
1017
  mapView.addAnnotation(annotation)
850
1018
  return
851
1019
  }
852
1020
 
853
- if let image = createImageFromSubviews() {
854
- annotationView.image = image
855
- applyCenterOffset(to: annotationView, defaultOffset: .zero)
856
- annotationView.canShowCallout = false
857
- annotationView.isDraggable = draggable
858
- lastRenderedChildrenSignature = signature
1021
+ let size = resolvedContentSubviewSize(defaultSize: CGSize(width: 200, height: 40))
1022
+ if let image = createImageFromSubviews(size: size) {
1023
+ applyChildrenImage(image, to: annotationView, signature: signature)
859
1024
  }
860
1025
  }
861
1026
 
@@ -1023,7 +1188,7 @@ class MarkerView: ExpoView {
1023
1188
  guard contentWidth != width else { return }
1024
1189
  contentWidth = width
1025
1190
  if !subviews.isEmpty {
1026
- refreshAnnotationAppearance(invalidateChildrenCache: true)
1191
+ scheduleChildrenImageRefresh(invalidateChildrenCache: true)
1027
1192
  }
1028
1193
  }
1029
1194
 
@@ -1031,7 +1196,7 @@ class MarkerView: ExpoView {
1031
1196
  guard contentHeight != height else { return }
1032
1197
  contentHeight = height
1033
1198
  if !subviews.isEmpty {
1034
- refreshAnnotationAppearance(invalidateChildrenCache: true)
1199
+ scheduleChildrenImageRefresh(invalidateChildrenCache: true)
1035
1200
  }
1036
1201
  }
1037
1202
 
@@ -1281,6 +1446,8 @@ class MarkerView: ExpoView {
1281
1446
  pendingAddTask?.cancel()
1282
1447
  pendingUpdateTask?.cancel()
1283
1448
  pendingSubviewRefreshTask?.cancel()
1449
+ pendingCacheKeyRefreshTask?.cancel()
1450
+ pendingAnnotationRemovalTask?.cancel()
1284
1451
 
1285
1452
  if Thread.isMainThread {
1286
1453
  cleanupAnnotationFromMap()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-gaode-map",
3
- "version": "2.2.38",
3
+ "version": "2.2.39",
4
4
  "description": "Expo Modules AMap (Gaode Map) stack for Expo/React Native: Config Plugin, New Architecture support, maps, location, search, offline maps, and react-native-amap3d migration guidance.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -18,7 +18,7 @@
18
18
  "build": "expo-module build && yarn build:plugin",
19
19
  "build:plugin": "tsc --project plugin/tsconfig.json",
20
20
  "clean": "expo-module clean && rm -rf plugin/build",
21
- "lint": "expo-module lint",
21
+ "lint": "eslint \"src/**/*.{ts,tsx}\"",
22
22
  "test": "npx jest --no-watchman --config jest.config.js --runInBand",
23
23
  "prepare": "expo-module prepare && yarn build:plugin",
24
24
  "postinstall": "node scripts/check-expo-modules.js",
@@ -75,13 +75,15 @@
75
75
  "@babel/runtime": "^7.25.7",
76
76
  "@testing-library/react-native": "^13.3.3",
77
77
  "@types/jest": "^29.5.14",
78
+ "@types/node": "^22.18.0",
78
79
  "@types/react": "~19.2.10",
79
- "expo": "^55.0.8",
80
- "expo-module-scripts": "^55.0.2",
80
+ "eslint": "^9.25.1",
81
+ "expo": "^57.0.1",
82
+ "expo-module-scripts": "^56.0.3",
81
83
  "jest": "~29.7.0",
82
- "jest-expo": "~55.0.11",
83
- "react-native": "0.83.2",
84
- "typescript": "^5.9.3"
84
+ "jest-expo": "~57.0.0",
85
+ "react-native": "0.86.0",
86
+ "typescript": "^6.0.3"
85
87
  },
86
88
  "peerDependencies": {
87
89
  "expo": "*",
@@ -146,8 +146,9 @@ const withGaodeMapAndroidManifest = (config, props) => {
146
146
  else {
147
147
  // 更新现有的 API Key
148
148
  const apiKeyIndex = mainApplication['meta-data'].findIndex((item) => item.$?.['android:name'] === 'com.amap.api.v2.apikey');
149
- if (apiKeyIndex !== -1) {
150
- mainApplication['meta-data'][apiKeyIndex].$ = {
149
+ const apiKeyMetaData = mainApplication['meta-data'][apiKeyIndex];
150
+ if (apiKeyMetaData) {
151
+ apiKeyMetaData.$ = {
151
152
  'android:name': 'com.amap.api.v2.apikey',
152
153
  'android:value': props.androidKey,
153
154
  };