react-native-google-maps-plus 0.1.0 → 1.0.1

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 (183) hide show
  1. package/GoogleMapsNitro.podspec +34 -0
  2. package/LICENSE +20 -0
  3. package/README.md +40 -0
  4. package/android/CMakeLists.txt +32 -0
  5. package/android/build.gradle +135 -0
  6. package/android/fix-prefab.gradle +51 -0
  7. package/android/gradle.properties +8 -0
  8. package/android/src/main/AndroidManifest.xml +2 -0
  9. package/android/src/main/cpp/cpp-adapter.cpp +6 -0
  10. package/android/src/main/java/com/googlemapsnitro/Color.kt +65 -0
  11. package/android/src/main/java/com/googlemapsnitro/GoogleMapsNitroPackage.kt +35 -0
  12. package/android/src/main/java/com/googlemapsnitro/GoogleMapsNitroViewImpl.kt +720 -0
  13. package/android/src/main/java/com/googlemapsnitro/HybridGoogleMapsNitroModule.kt +22 -0
  14. package/android/src/main/java/com/googlemapsnitro/HybridGoogleMapsNitroView.kt +337 -0
  15. package/android/src/main/java/com/googlemapsnitro/LocationHandler.kt +205 -0
  16. package/android/src/main/java/com/googlemapsnitro/MapMarker.kt +145 -0
  17. package/android/src/main/java/com/googlemapsnitro/MapPolygon.kt +36 -0
  18. package/android/src/main/java/com/googlemapsnitro/MapPolyline.kt +59 -0
  19. package/android/src/main/java/com/googlemapsnitro/PermissionHandler.kt +116 -0
  20. package/android/src/main/java/com/googlemapsnitro/PlayServicesHandler.kt +25 -0
  21. package/ios/Color.swift +109 -0
  22. package/ios/GoogleMapNitroViewImpl.swift +590 -0
  23. package/ios/HybridGoogleMapsNitroModule.swift +27 -0
  24. package/ios/HybridGoogleMapsNitroView.swift +348 -0
  25. package/ios/LocationHandler.swift +205 -0
  26. package/ios/MapHelper.swift +18 -0
  27. package/ios/MapMarker.swift +207 -0
  28. package/ios/MapPolygon.swift +55 -0
  29. package/ios/MapPolyline.swift +83 -0
  30. package/ios/PermissionHandler.swift +73 -0
  31. package/lib/module/GoogleMapsNitroModule.nitro.js +4 -0
  32. package/lib/module/GoogleMapsNitroModule.nitro.js.map +1 -0
  33. package/lib/module/GoogleMapsNitroView.nitro.js +4 -0
  34. package/lib/module/GoogleMapsNitroView.nitro.js.map +1 -0
  35. package/lib/module/index.js +8 -0
  36. package/lib/module/index.js.map +1 -0
  37. package/lib/module/package.json +1 -0
  38. package/lib/module/types.js +78 -0
  39. package/lib/module/types.js.map +1 -0
  40. package/lib/typescript/package.json +1 -0
  41. package/lib/typescript/src/GoogleMapsNitroModule.nitro.d.ts +12 -0
  42. package/lib/typescript/src/GoogleMapsNitroModule.nitro.d.ts.map +1 -0
  43. package/lib/typescript/src/GoogleMapsNitroView.nitro.d.ts +34 -0
  44. package/lib/typescript/src/GoogleMapsNitroView.nitro.d.ts.map +1 -0
  45. package/lib/typescript/src/index.d.ts +7 -0
  46. package/lib/typescript/src/index.d.ts.map +1 -0
  47. package/lib/typescript/src/types.d.ts +113 -0
  48. package/lib/typescript/src/types.d.ts.map +1 -0
  49. package/nitro.json +28 -0
  50. package/nitrogen/generated/.gitattributes +1 -0
  51. package/nitrogen/generated/android/GoogleMapsNitro+autolinking.cmake +85 -0
  52. package/nitrogen/generated/android/GoogleMapsNitro+autolinking.gradle +27 -0
  53. package/nitrogen/generated/android/GoogleMapsNitroOnLoad.cpp +70 -0
  54. package/nitrogen/generated/android/GoogleMapsNitroOnLoad.hpp +25 -0
  55. package/nitrogen/generated/android/c++/JFunc_void_RNLatLng.hpp +76 -0
  56. package/nitrogen/generated/android/c++/JFunc_void_RNLocation.hpp +78 -0
  57. package/nitrogen/generated/android/c++/JFunc_void_RNLocationErrorCode.hpp +76 -0
  58. package/nitrogen/generated/android/c++/JFunc_void_RNMapErrorCode.hpp +76 -0
  59. package/nitrogen/generated/android/c++/JFunc_void_RNRegion_RNCamera_bool.hpp +81 -0
  60. package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +74 -0
  61. package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +75 -0
  62. package/nitrogen/generated/android/c++/JHybridGoogleMapsNitroModuleSpec.cpp +83 -0
  63. package/nitrogen/generated/android/c++/JHybridGoogleMapsNitroModuleSpec.hpp +67 -0
  64. package/nitrogen/generated/android/c++/JHybridGoogleMapsNitroViewSpec.cpp +485 -0
  65. package/nitrogen/generated/android/c++/JHybridGoogleMapsNitroViewSpec.hpp +108 -0
  66. package/nitrogen/generated/android/c++/JRNAndroidLocationPermissionResult.hpp +62 -0
  67. package/nitrogen/generated/android/c++/JRNCamera.hpp +67 -0
  68. package/nitrogen/generated/android/c++/JRNIOSPermissionResult.hpp +59 -0
  69. package/nitrogen/generated/android/c++/JRNLatLng.hpp +57 -0
  70. package/nitrogen/generated/android/c++/JRNLineCapType.hpp +62 -0
  71. package/nitrogen/generated/android/c++/JRNLineJoinType.hpp +62 -0
  72. package/nitrogen/generated/android/c++/JRNLocation.hpp +58 -0
  73. package/nitrogen/generated/android/c++/JRNLocationErrorCode.hpp +71 -0
  74. package/nitrogen/generated/android/c++/JRNLocationPermissionResult.hpp +61 -0
  75. package/nitrogen/generated/android/c++/JRNMapErrorCode.hpp +74 -0
  76. package/nitrogen/generated/android/c++/JRNMapPadding.hpp +65 -0
  77. package/nitrogen/generated/android/c++/JRNMarker.hpp +82 -0
  78. package/nitrogen/generated/android/c++/JRNPolygon.hpp +94 -0
  79. package/nitrogen/generated/android/c++/JRNPolyline.hpp +102 -0
  80. package/nitrogen/generated/android/c++/JRNPosition.hpp +57 -0
  81. package/nitrogen/generated/android/c++/JRNRegion.hpp +62 -0
  82. package/nitrogen/generated/android/c++/JRNUserInterfaceStyle.hpp +62 -0
  83. package/nitrogen/generated/android/c++/views/JHybridGoogleMapsNitroViewStateUpdater.cpp +132 -0
  84. package/nitrogen/generated/android/c++/views/JHybridGoogleMapsNitroViewStateUpdater.hpp +49 -0
  85. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/Func_void_RNLatLng.kt +81 -0
  86. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/Func_void_RNLocation.kt +81 -0
  87. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/Func_void_RNLocationErrorCode.kt +81 -0
  88. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/Func_void_RNMapErrorCode.kt +81 -0
  89. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/Func_void_RNRegion_RNCamera_bool.kt +81 -0
  90. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/Func_void_bool.kt +81 -0
  91. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/Func_void_std__string.kt +81 -0
  92. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/GoogleMapsNitroOnLoad.kt +35 -0
  93. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/HybridGoogleMapsNitroModuleSpec.kt +64 -0
  94. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/HybridGoogleMapsNitroViewSpec.kt +263 -0
  95. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNAndroidLocationPermissionResult.kt +22 -0
  96. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNCamera.kt +38 -0
  97. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNIOSPermissionResult.kt +21 -0
  98. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNLatLng.kt +32 -0
  99. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNLineCapType.kt +22 -0
  100. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNLineJoinType.kt +22 -0
  101. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNLocation.kt +32 -0
  102. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNLocationErrorCode.kt +25 -0
  103. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNLocationPermissionResult.kt +32 -0
  104. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNMapErrorCode.kt +26 -0
  105. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNMapPadding.kt +38 -0
  106. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNMarker.kt +47 -0
  107. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNPolygon.kt +44 -0
  108. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNPolyline.kt +47 -0
  109. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNPosition.kt +32 -0
  110. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNRegion.kt +35 -0
  111. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNUserInterfaceStyle.kt +22 -0
  112. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/views/HybridGoogleMapsNitroViewManager.kt +50 -0
  113. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/views/HybridGoogleMapsNitroViewStateUpdater.kt +23 -0
  114. package/nitrogen/generated/ios/GoogleMapsNitro+autolinking.rb +60 -0
  115. package/nitrogen/generated/ios/GoogleMapsNitro-Swift-Cxx-Bridge.cpp +121 -0
  116. package/nitrogen/generated/ios/GoogleMapsNitro-Swift-Cxx-Bridge.hpp +649 -0
  117. package/nitrogen/generated/ios/GoogleMapsNitro-Swift-Cxx-Umbrella.hpp +104 -0
  118. package/nitrogen/generated/ios/GoogleMapsNitroAutolinking.mm +41 -0
  119. package/nitrogen/generated/ios/GoogleMapsNitroAutolinking.swift +40 -0
  120. package/nitrogen/generated/ios/c++/HybridGoogleMapsNitroModuleSpecSwift.cpp +11 -0
  121. package/nitrogen/generated/ios/c++/HybridGoogleMapsNitroModuleSpecSwift.hpp +102 -0
  122. package/nitrogen/generated/ios/c++/HybridGoogleMapsNitroViewSpecSwift.cpp +11 -0
  123. package/nitrogen/generated/ios/c++/HybridGoogleMapsNitroViewSpecSwift.hpp +294 -0
  124. package/nitrogen/generated/ios/c++/views/HybridGoogleMapsNitroViewComponent.mm +191 -0
  125. package/nitrogen/generated/ios/swift/Func_void_RNLatLng.swift +47 -0
  126. package/nitrogen/generated/ios/swift/Func_void_RNLocation.swift +47 -0
  127. package/nitrogen/generated/ios/swift/Func_void_RNLocationErrorCode.swift +47 -0
  128. package/nitrogen/generated/ios/swift/Func_void_RNLocationPermissionResult.swift +47 -0
  129. package/nitrogen/generated/ios/swift/Func_void_RNMapErrorCode.swift +47 -0
  130. package/nitrogen/generated/ios/swift/Func_void_RNRegion_RNCamera_bool.swift +47 -0
  131. package/nitrogen/generated/ios/swift/Func_void_bool.swift +47 -0
  132. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
  133. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
  134. package/nitrogen/generated/ios/swift/HybridGoogleMapsNitroModuleSpec.swift +52 -0
  135. package/nitrogen/generated/ios/swift/HybridGoogleMapsNitroModuleSpec_cxx.swift +164 -0
  136. package/nitrogen/generated/ios/swift/HybridGoogleMapsNitroViewSpec.swift +73 -0
  137. package/nitrogen/generated/ios/swift/HybridGoogleMapsNitroViewSpec_cxx.swift +630 -0
  138. package/nitrogen/generated/ios/swift/RNAndroidLocationPermissionResult.swift +44 -0
  139. package/nitrogen/generated/ios/swift/RNCamera.swift +123 -0
  140. package/nitrogen/generated/ios/swift/RNIOSPermissionResult.swift +40 -0
  141. package/nitrogen/generated/ios/swift/RNLatLng.swift +46 -0
  142. package/nitrogen/generated/ios/swift/RNLineCapType.swift +44 -0
  143. package/nitrogen/generated/ios/swift/RNLineJoinType.swift +44 -0
  144. package/nitrogen/generated/ios/swift/RNLocation.swift +46 -0
  145. package/nitrogen/generated/ios/swift/RNLocationErrorCode.swift +56 -0
  146. package/nitrogen/generated/ios/swift/RNLocationPermissionResult.swift +70 -0
  147. package/nitrogen/generated/ios/swift/RNMapErrorCode.swift +60 -0
  148. package/nitrogen/generated/ios/swift/RNMapPadding.swift +68 -0
  149. package/nitrogen/generated/ios/swift/RNMarker.swift +120 -0
  150. package/nitrogen/generated/ios/swift/RNPolygon.swift +152 -0
  151. package/nitrogen/generated/ios/swift/RNPolyline.swift +168 -0
  152. package/nitrogen/generated/ios/swift/RNPosition.swift +46 -0
  153. package/nitrogen/generated/ios/swift/RNRegion.swift +57 -0
  154. package/nitrogen/generated/ios/swift/RNUserInterfaceStyle.swift +44 -0
  155. package/nitrogen/generated/shared/c++/HybridGoogleMapsNitroModuleSpec.cpp +24 -0
  156. package/nitrogen/generated/shared/c++/HybridGoogleMapsNitroModuleSpec.hpp +67 -0
  157. package/nitrogen/generated/shared/c++/HybridGoogleMapsNitroViewSpec.cpp +66 -0
  158. package/nitrogen/generated/shared/c++/HybridGoogleMapsNitroViewSpec.hpp +145 -0
  159. package/nitrogen/generated/shared/c++/RNAndroidLocationPermissionResult.hpp +67 -0
  160. package/nitrogen/generated/shared/c++/RNCamera.hpp +81 -0
  161. package/nitrogen/generated/shared/c++/RNIOSPermissionResult.hpp +65 -0
  162. package/nitrogen/generated/shared/c++/RNLatLng.hpp +71 -0
  163. package/nitrogen/generated/shared/c++/RNLineCapType.hpp +80 -0
  164. package/nitrogen/generated/shared/c++/RNLineJoinType.hpp +80 -0
  165. package/nitrogen/generated/shared/c++/RNLocation.hpp +72 -0
  166. package/nitrogen/generated/shared/c++/RNLocationErrorCode.hpp +73 -0
  167. package/nitrogen/generated/shared/c++/RNLocationPermissionResult.hpp +76 -0
  168. package/nitrogen/generated/shared/c++/RNMapErrorCode.hpp +67 -0
  169. package/nitrogen/generated/shared/c++/RNMapPadding.hpp +79 -0
  170. package/nitrogen/generated/shared/c++/RNMarker.hpp +97 -0
  171. package/nitrogen/generated/shared/c++/RNPolygon.hpp +91 -0
  172. package/nitrogen/generated/shared/c++/RNPolyline.hpp +101 -0
  173. package/nitrogen/generated/shared/c++/RNPosition.hpp +71 -0
  174. package/nitrogen/generated/shared/c++/RNRegion.hpp +76 -0
  175. package/nitrogen/generated/shared/c++/RNUserInterfaceStyle.hpp +80 -0
  176. package/nitrogen/generated/shared/c++/views/HybridGoogleMapsNitroViewComponent.cpp +315 -0
  177. package/nitrogen/generated/shared/c++/views/HybridGoogleMapsNitroViewComponent.hpp +139 -0
  178. package/nitrogen/generated/shared/json/GoogleMapsNitroViewConfig.json +29 -0
  179. package/package.json +13 -3
  180. package/src/GoogleMapsNitroModule.nitro.ts +13 -0
  181. package/src/GoogleMapsNitroView.nitro.ts +78 -0
  182. package/src/index.tsx +24 -0
  183. package/src/types.ts +174 -0
@@ -0,0 +1,348 @@
1
+ import CoreLocation
2
+ import Foundation
3
+ import GoogleMaps
4
+ import NitroModules
5
+
6
+ final class HybridGoogleMapsNitroView: HybridGoogleMapsNitroViewSpec {
7
+
8
+ private let permissionHandler: PermissionHandler
9
+ private let locationHandler: LocationHandler
10
+
11
+ private let impl: GoogleMapsNitroViewImpl
12
+
13
+ var view: UIView {
14
+ return impl
15
+ }
16
+
17
+ private var currentCustomMapStyle: String = ""
18
+ private let markerOptions = MapMarkerOptions()
19
+ private let polylineOptions = MapPolylineOptions()
20
+ private let polygonOptions = MapPolygonOptions()
21
+
22
+ override init() {
23
+ self.permissionHandler = PermissionHandler()
24
+ self.locationHandler = LocationHandler()
25
+ self.impl = GoogleMapsNitroViewImpl(
26
+ locationHandler: locationHandler,
27
+ markerOptions: markerOptions
28
+ )
29
+ }
30
+
31
+ @MainActor
32
+ var buildingEnabled: Bool {
33
+ get { impl.buildingEnabled }
34
+ set { impl.buildingEnabled = newValue }
35
+ }
36
+
37
+ @MainActor
38
+ var trafficEnabled: Bool {
39
+ get { impl.trafficEnabled }
40
+ set { impl.trafficEnabled = newValue }
41
+ }
42
+
43
+ @MainActor
44
+ var customMapStyle: String {
45
+ get { currentCustomMapStyle }
46
+ set {
47
+ currentCustomMapStyle = newValue
48
+ impl.customMapStyle = try? GMSMapStyle(jsonString: newValue)
49
+ }
50
+ }
51
+
52
+ @MainActor
53
+ var initialCamera: RNCamera {
54
+ get { mapCameraPositionToCamera(impl.initialCamera) }
55
+ set { impl.initialCamera = mapCameraToGMSCamera(newValue) }
56
+ }
57
+
58
+ @MainActor
59
+ var userInterfaceStyle: RNUserInterfaceStyle {
60
+ get { mapUIUserInterfaceStyletoUserInterfaceStyle(impl.userInterfaceStyle) }
61
+ set {
62
+ impl.userInterfaceStyle = mapUserInterfaceStyleToUIUserInterfaceStyle(
63
+ newValue
64
+ )
65
+ }
66
+ }
67
+
68
+ @MainActor
69
+ var minZoomLevel: Double {
70
+ get { impl.minZoomLevel }
71
+ set { impl.minZoomLevel = newValue }
72
+ }
73
+
74
+ @MainActor
75
+ var maxZoomLevel: Double {
76
+ get { impl.maxZoomLevel }
77
+ set { impl.maxZoomLevel = newValue }
78
+ }
79
+
80
+ @MainActor
81
+ var mapPadding: RNMapPadding {
82
+ get { impl.mapPadding }
83
+ set { impl.mapPadding = newValue }
84
+ }
85
+
86
+ @MainActor
87
+ var markers: [RNMarker] = [] {
88
+ didSet {
89
+ let prevById = Dictionary(
90
+ oldValue.map { ($0.id, $0) },
91
+ uniquingKeysWith: { _, new in new }
92
+ )
93
+ let nextById = Dictionary(
94
+ markers.map { ($0.id, $0) },
95
+ uniquingKeysWith: { _, new in new }
96
+ )
97
+
98
+ let removed = Set(prevById.keys).subtracting(nextById.keys)
99
+ withCATransaction(disableActions: true) {
100
+
101
+ removed.forEach {
102
+ impl.removeMarker(id: $0)
103
+ markerOptions.cancelIconTask($0)
104
+ }
105
+
106
+ for (id, next) in nextById {
107
+ if let prev = prevById[id] {
108
+ if !prev.markerEquals(next) {
109
+ impl.updateMarker(id: id) { m in
110
+ self.markerOptions.updateMarker(prev, next, m)
111
+ }
112
+ }
113
+ } else {
114
+ markerOptions.buildIconAsync(next.id, next) { icon in
115
+ guard let icon else { return }
116
+ let marker = self.markerOptions.build(next, icon: icon)
117
+ self.impl.addMarker(id: id, marker: marker)
118
+ }
119
+ }
120
+ }
121
+ }
122
+ }
123
+ }
124
+
125
+ @MainActor
126
+ var polylines: [RNPolyline] = [] {
127
+ didSet {
128
+ let prevById = Dictionary(
129
+ oldValue.map { ($0.id, $0) },
130
+ uniquingKeysWith: { _, new in new }
131
+ )
132
+ let nextById = Dictionary(
133
+ polylines.map { ($0.id, $0) },
134
+ uniquingKeysWith: { _, new in new }
135
+ )
136
+
137
+ let removed = Set(prevById.keys).subtracting(nextById.keys)
138
+ removed.forEach { impl.removePolyline(id: $0) }
139
+
140
+ for (id, next) in nextById {
141
+ if let prev = prevById[id] {
142
+ if !prev.polylineEquals(next) {
143
+ impl.updatePolyline(id: id) { gms in
144
+ prev.updatePolyline(next, gms)
145
+ }
146
+ } else {
147
+ impl.addPolyline(
148
+ id: id,
149
+ polyline: polylineOptions.buildPolyline(next)
150
+ )
151
+ }
152
+ }
153
+ }
154
+ }
155
+ }
156
+
157
+ @MainActor
158
+ var polygons: [RNPolygon] = [] {
159
+ didSet {
160
+ let prevById = Dictionary(
161
+ oldValue.map { ($0.id, $0) },
162
+ uniquingKeysWith: { _, new in new }
163
+ )
164
+ let nextById = Dictionary(
165
+ polygons.map { ($0.id, $0) },
166
+ uniquingKeysWith: { _, new in new }
167
+ )
168
+
169
+ let removed = Set(prevById.keys).subtracting(nextById.keys)
170
+ removed.forEach { impl.removePolygon(id: $0) }
171
+
172
+ for (id, next) in nextById {
173
+ if let prev = prevById[id] {
174
+ if !prev.polygonEquals(next) {
175
+ impl.updatePolygon(id: id) { pg in
176
+ prev.updatePolygon(next, pg)
177
+ }
178
+ }
179
+ } else {
180
+ impl.addPolygon(id: id, polygon: polygonOptions.buildPolygon(next))
181
+ }
182
+ }
183
+ }
184
+ }
185
+
186
+ func setCamera(camera: RNCamera, animated: Bool?, durationMS: Double?) {
187
+ onMain {
188
+ self.impl.setCamera(
189
+ camera: camera,
190
+ animated: animated ?? true,
191
+ durationMS: durationMS ?? 3000
192
+ )
193
+ }
194
+ }
195
+
196
+ func setCameraToCoordinates(
197
+ coordinates: [RNLatLng],
198
+ padding: RNMapPadding?,
199
+ animated: Bool?,
200
+ durationMS: Double?
201
+ ) {
202
+ onMain {
203
+ self.impl.setCameraToCoordinates(
204
+ coordinates: coordinates,
205
+ padding: padding ?? RNMapPadding(0, 0, 0, 0),
206
+ animated: animated ?? true,
207
+ durationMS: durationMS ?? 3000
208
+ )
209
+ }
210
+ }
211
+
212
+ var onMapError: ((RNMapErrorCode) -> Void)? {
213
+ get { impl.onMapError }
214
+ set { impl.onMapError = newValue }
215
+ }
216
+ var onMapReady: ((Bool) -> Void)? {
217
+ get { impl.onMapReady }
218
+ set { impl.onMapReady = newValue }
219
+ }
220
+ var onLocationUpdate: ((RNLocation) -> Void)? {
221
+ get { impl.onLocationUpdate }
222
+ set { impl.onLocationUpdate = newValue }
223
+ }
224
+ var onLocationError: ((_ error: RNLocationErrorCode) -> Void)? {
225
+ get { impl.onLocationError }
226
+ set { impl.onLocationError = newValue }
227
+ }
228
+ var onMapPress: ((RNLatLng) -> Void)? {
229
+ get { impl.onMapPress }
230
+ set { impl.onMapPress = newValue }
231
+ }
232
+ var onMarkerPress: ((String) -> Void)? {
233
+ get { impl.onMarkerPress }
234
+ set { impl.onMarkerPress = newValue }
235
+ }
236
+ var onCameraChangeStart: ((RNRegion, RNCamera, Bool) -> Void)? {
237
+ get { impl.onCameraChangeStart }
238
+ set { impl.onCameraChangeStart = newValue }
239
+ }
240
+ var onCameraChange: ((RNRegion, RNCamera, Bool) -> Void)? {
241
+ get { impl.onCameraChange }
242
+ set { impl.onCameraChange = newValue }
243
+ }
244
+ var onCameraChangeComplete: ((RNRegion, RNCamera, Bool) -> Void)? {
245
+ get { impl.onCameraChangeComplete }
246
+ set { impl.onCameraChangeComplete = newValue }
247
+ }
248
+
249
+ func showLocationDialog() {
250
+ locationHandler.showLocationDialog()
251
+ }
252
+
253
+ func openLocationSettings() {
254
+ locationHandler.openLocationSettings()
255
+ }
256
+
257
+ func requestLocationPermission()
258
+ -> NitroModules.Promise<RNLocationPermissionResult> {
259
+ return permissionHandler.requestLocationPermission()
260
+ }
261
+
262
+ func isGooglePlayServicesAvailable() -> Bool {
263
+ /// not supported
264
+ return true
265
+ }
266
+
267
+ private func mapCameraToGMSCamera(_ c: RNCamera) -> GMSCameraPosition {
268
+ let current = impl.currentCamera
269
+ let center = CLLocationCoordinate2D(
270
+ latitude: c.center?.latitude ?? current.target.latitude,
271
+ longitude: c.center?.longitude ?? current.target.longitude
272
+ )
273
+ let z = Float(c.zoom ?? Double(current.zoom))
274
+ let b = c.bearing ?? current.bearing
275
+ let t = c.tilt ?? current.viewingAngle
276
+
277
+ return GMSCameraPosition.camera(
278
+ withTarget: center,
279
+ zoom: z,
280
+ bearing: b,
281
+ viewingAngle: t
282
+ )
283
+ }
284
+
285
+ private func mapCameraPositionToCamera(_ cp: GMSCameraPosition)
286
+ -> RNCamera {
287
+ return RNCamera(
288
+ center: RNLatLng(
289
+ latitude: cp.target.latitude,
290
+ longitude: cp.target.longitude
291
+ ),
292
+ zoom: Double(cp.zoom),
293
+ bearing: cp.bearing,
294
+ tilt: cp.viewingAngle
295
+ )
296
+ }
297
+
298
+ func mapUserInterfaceStyleToUIUserInterfaceStyle(
299
+ _ style: RNUserInterfaceStyle
300
+ )
301
+ -> UIUserInterfaceStyle {
302
+ switch style {
303
+ case .light: return .light
304
+ case .dark: return .dark
305
+ case .default: return .unspecified
306
+ }
307
+ }
308
+
309
+ func mapUIUserInterfaceStyletoUserInterfaceStyle(
310
+ _ uiStyle: UIUserInterfaceStyle
311
+ ) -> RNUserInterfaceStyle {
312
+ switch uiStyle {
313
+ case .light: return .light
314
+ case .dark: return .dark
315
+ case .unspecified: return .default
316
+ @unknown default: return .default
317
+ }
318
+ }
319
+ }
320
+
321
+ extension UIUserInterfaceStyle {
322
+ init?(fromString string: String) {
323
+ switch string.lowercased() {
324
+ case "light": self = .light
325
+ case "dark": self = .dark
326
+ case "default": self = .unspecified
327
+ default: return nil
328
+ }
329
+ }
330
+
331
+ var stringValue: String {
332
+ switch self {
333
+ case .light: return "light"
334
+ case .dark: return "dark"
335
+ case .unspecified: return "default"
336
+ @unknown default: return "default"
337
+ }
338
+ }
339
+ }
340
+
341
+ @inline(__always)
342
+ func onMain(_ block: @escaping () -> Void) {
343
+ if Thread.isMainThread {
344
+ block()
345
+ } else {
346
+ DispatchQueue.main.async { block() }
347
+ }
348
+ }
@@ -0,0 +1,205 @@
1
+ import CoreLocation
2
+ import Foundation
3
+ import UIKit
4
+
5
+ final class LocationHandler: NSObject, CLLocationManagerDelegate {
6
+
7
+ private let manager = CLLocationManager()
8
+ private var priority: Int = Priority.highAccuracy.rawValue
9
+ private var interval: TimeInterval = 5.0
10
+ private var minUpdateInterval: TimeInterval = 5.0
11
+ private var distanceFilterMeters: CLLocationDistance = kCLDistanceFilterNone
12
+
13
+ var onUpdate: ((CLLocation) -> Void)?
14
+ var onError: ((_ error: RNLocationErrorCode) -> Void)?
15
+
16
+ private var lastEmit: Date?
17
+
18
+ override init() {
19
+ super.init()
20
+ manager.delegate = self
21
+ manager.pausesLocationUpdatesAutomatically = true
22
+ manager.activityType = .other
23
+ applyPriority()
24
+ }
25
+
26
+ func setPriority(_ priority: Int) {
27
+ self.priority = priority
28
+ applyPriority()
29
+ }
30
+
31
+ func setInterval(_ seconds: Int) {
32
+ self.interval = max(0, TimeInterval(seconds))
33
+ }
34
+
35
+ func setFastestInterval(_ seconds: Int) {
36
+ self.minUpdateInterval = max(0, TimeInterval(seconds))
37
+ }
38
+
39
+ func setDistanceFilter(_ meters: Double) {
40
+ self.distanceFilterMeters = meters >= 0 ? meters : kCLDistanceFilterNone
41
+ manager.distanceFilter = distanceFilterMeters
42
+ }
43
+
44
+ func showLocationDialog() {
45
+ DispatchQueue.main.async {
46
+ guard let vc = Self.topMostViewController() else { return }
47
+ let title =
48
+ Bundle.main.object(forInfoDictionaryKey: "LocationNotAvailableTitle")
49
+ as? String
50
+ let message =
51
+ Bundle.main.object(forInfoDictionaryKey: "LocationNotAvailableMessage")
52
+ as? String
53
+ let cancelButton =
54
+ Bundle.main.object(forInfoDictionaryKey: "CancelButton") as? String
55
+ let openLocationSettingsButton =
56
+ Bundle.main.object(forInfoDictionaryKey: "OpenLocationAlertButton")
57
+ as? String
58
+
59
+ let alert = UIAlertController(
60
+ title: title ?? "Location not available",
61
+ message: message ?? "Please check your location settings.",
62
+ preferredStyle: .alert
63
+ )
64
+ alert.addAction(
65
+ UIAlertAction(title: cancelButton ?? "Cancel", style: .cancel)
66
+ )
67
+ alert.addAction(
68
+ UIAlertAction(
69
+ title: openLocationSettingsButton ?? "Open settings",
70
+ style: .default
71
+ ) { _ in
72
+ self.openLocationSettings()
73
+ }
74
+ )
75
+ vc.present(alert, animated: true, completion: nil)
76
+ }
77
+ }
78
+
79
+ func start() {
80
+ stop()
81
+ startUpdates()
82
+ }
83
+
84
+ func stop() {
85
+ manager.stopUpdatingLocation()
86
+ }
87
+
88
+ func openLocationSettings() {
89
+ DispatchQueue.main.async {
90
+ let openSettings = {
91
+ if #available(iOS 18.3, *) {
92
+ guard
93
+ let url = URL(
94
+ string: UIApplication.openDefaultApplicationsSettingsURLString
95
+ )
96
+ else {
97
+ return
98
+ }
99
+ UIApplication.shared.open(url, options: [:], completionHandler: nil)
100
+ } else {
101
+ guard let url = URL(string: UIApplication.openSettingsURLString)
102
+ else {
103
+ return
104
+ }
105
+ UIApplication.shared.open(url, options: [:], completionHandler: nil)
106
+ }
107
+ }
108
+
109
+ openSettings()
110
+ }
111
+ }
112
+
113
+ private func applyPriority() {
114
+ guard let p = Priority(rawValue: priority) else {
115
+ manager.desiredAccuracy = kCLLocationAccuracyBest
116
+ return
117
+ }
118
+ switch p {
119
+ case .highAccuracy:
120
+ manager.desiredAccuracy = kCLLocationAccuracyBest
121
+ case .balanced:
122
+ manager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
123
+ case .lowPower:
124
+ manager.desiredAccuracy = kCLLocationAccuracyHundredMeters
125
+ case .passive:
126
+ manager.desiredAccuracy = kCLLocationAccuracyKilometer
127
+ }
128
+ }
129
+
130
+ private func startUpdates() {
131
+ manager.distanceFilter = distanceFilterMeters
132
+ manager.startUpdatingLocation()
133
+ }
134
+
135
+ private func shouldEmit(now: Date) -> Bool {
136
+ if let last = lastEmit {
137
+ let delta = now.timeIntervalSince(last)
138
+ if delta < minUpdateInterval { return false }
139
+ }
140
+ return true
141
+ }
142
+
143
+ func locationManager(
144
+ _ manager: CLLocationManager,
145
+ didFailWithError error: Error
146
+ ) {
147
+ let code: RNLocationErrorCode
148
+
149
+ if let clError = error as? CLError {
150
+ switch clError.code {
151
+ case .denied:
152
+ code = RNLocationErrorCode.permissionDenied
153
+ case .locationUnknown, .network:
154
+ code = RNLocationErrorCode.positionUnavailable
155
+ default:
156
+ code = RNLocationErrorCode.internalError
157
+ }
158
+ } else {
159
+ code = RNLocationErrorCode.internalError
160
+ }
161
+ onError?(code)
162
+ }
163
+
164
+ func locationManager(
165
+ _ manager: CLLocationManager,
166
+ didUpdateLocations locations: [CLLocation]
167
+ ) {
168
+ guard let loc = locations.last else { return }
169
+ let now = Date()
170
+
171
+ if shouldEmit(now: now) {
172
+ lastEmit = now
173
+ onUpdate?(loc)
174
+ }
175
+ }
176
+
177
+ private static func topMostViewController() -> UIViewController? {
178
+ let scenes = UIApplication.shared.connectedScenes
179
+ .compactMap { $0 as? UIWindowScene }
180
+ .filter { $0.activationState == .foregroundActive }
181
+
182
+ guard
183
+ let window = scenes.flatMap({ $0.windows }).first(where: {
184
+ $0.isKeyWindow
185
+ }),
186
+ var top = window.rootViewController
187
+ else { return nil }
188
+
189
+ while let presented = top.presentedViewController { top = presented }
190
+ return top
191
+ }
192
+
193
+ }
194
+
195
+ extension LocationHandler {
196
+ enum Priority: Int {
197
+ case highAccuracy = 100
198
+ /// Android: PRIORITY_BALANCED_POWER_ACCURACY
199
+ case balanced = 102
200
+ /// Android: PRIORITY_LOW_POWER
201
+ case lowPower = 104
202
+ /// Android: PRIORITY_PASSIVE
203
+ case passive = 105
204
+ }
205
+ }
@@ -0,0 +1,18 @@
1
+ import QuartzCore
2
+
3
+ @inline(__always)
4
+ func withCATransaction(
5
+ disableActions: Bool = true,
6
+ duration: CFTimeInterval? = nil,
7
+ timingFunction: CAMediaTimingFunction? = nil,
8
+ completion: (() -> Void)? = nil,
9
+ _ body: () -> Void
10
+ ) {
11
+ CATransaction.begin()
12
+ if disableActions { CATransaction.setDisableActions(true) }
13
+ if let d = duration { CATransaction.setAnimationDuration(d) }
14
+ if let tf = timingFunction { CATransaction.setAnimationTimingFunction(tf) }
15
+ if let c = completion { CATransaction.setCompletionBlock(c) }
16
+ body()
17
+ CATransaction.commit()
18
+ }