@woosmap/react-native-plugin-geofencing 0.13.2 → 1.0.0-beta.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 1.0.0
2
+ - Enhancement: Introduced the `WoosmapGeofencingTurbo` TurboModule (New Architecture).
3
+ — The region-CRUD and key/radius methods `addRegion`, `removeRegions`, `getRegions`, `setPoiRadius`, `setWoosmapApiKey` now dispatch through the generated codegen path. All other methods continue to flow through the legacy `PluginGeofencing` module. Public JS API is unchanged.
4
+
5
+ ## 0.14.0
6
+ - Breaking: Raised minimum supported React Native to `0.85.x`; React `19.2.3`.
7
+ - Breaking: Android requires JDK 17, Kotlin `2.1.x`, AGP `8.10.x`, Gradle `8.14.x`, `compileSdk`/`targetSdk` `36`.
8
+ - Breaking: Node.js `>=22` required by the app toolchain.
1
9
  ## 0.13.2
2
10
  - Patch: Internal refinement
3
11
 
package/README.md CHANGED
@@ -12,3 +12,19 @@ The SDK simplifies the integration of the location context in your mobile applic
12
12
  All feature descriptions and guides to implement the Woosmap Geofencing Android & iOS SDK are available on the [Woosmap developers documentation](https://developers.woosmap.com/products/geofencing-sdk/get-started/).
13
13
 
14
14
  If you are looking for the Woosmap Geofencing React Native plugin documentation, [we have a dedicated section for it](https://developers.woosmap.com/products/geofencing-sdk/react-native-plugin/guides/setup/).
15
+
16
+ ### Requirements
17
+
18
+ - React Native `>=0.85.0` and React `>=19.2.3`
19
+ - iOS `>=15.1`
20
+ - Android: JDK 17, `minSdk` 24, `compileSdk`/`targetSdk` 36
21
+ - Node.js `>=22`
22
+
23
+ ### React Native architectures
24
+
25
+ This release supports both the legacy bridge and the New Architecture (Fabric / TurboModules):
26
+
27
+ - **Legacy bridge** (`newArchEnabled=false` on Android, `RCT_NEW_ARCH_ENABLED=0` on iOS): the plugin is loaded natively as before.
28
+ - **New Architecture** (`newArchEnabled=true` / `RCT_NEW_ARCH_ENABLED=1`): the plugin is loaded through React Native's **interop layer**. No additional setup is required in your app — the plugin's native modules and event emitters are automatically wrapped as TurboModule-compatible instances at runtime.
29
+
30
+ A full TurboModule / Fabric-native rewrite is planned for a future major release. Until then, consumer apps can opt into the New Architecture without any changes to how they consume this plugin.
@@ -5,7 +5,7 @@ buildscript {
5
5
  }
6
6
 
7
7
  dependencies {
8
- classpath "com.android.tools.build:gradle:8.7.2"
8
+ classpath "com.android.tools.build:gradle:8.10.0"
9
9
  }
10
10
  }
11
11
 
@@ -17,6 +17,16 @@ apply plugin: "com.android.library"
17
17
 
18
18
  if (isNewArchitectureEnabled()) {
19
19
  apply plugin: "com.facebook.react"
20
+
21
+ // Drives TurboModule codegen for the WoosmapGeofencingTurbo spec
22
+ // (src/NativeWoosmapGeofencingTurbo.ts). Generates the abstract
23
+ // `NativeWoosmapGeofencingTurboSpec` class under `codegenJavaPackageName`,
24
+ // which WoosmapGeofencingTurboModule extends.
25
+ react {
26
+ jsRootDir = file("../src/")
27
+ libraryName = "WoosmapGeofencingTurbo"
28
+ codegenJavaPackageName = "com.woosmap.reactnativeplugingeofencing"
29
+ }
20
30
  }
21
31
 
22
32
  def getExtOrDefault(name) {
@@ -66,8 +76,8 @@ android {
66
76
  }
67
77
 
68
78
  compileOptions {
69
- sourceCompatibility JavaVersion.VERSION_1_8
70
- targetCompatibility JavaVersion.VERSION_1_8
79
+ sourceCompatibility JavaVersion.VERSION_17
80
+ targetCompatibility JavaVersion.VERSION_17
71
81
  }
72
82
  }
73
83
 
@@ -1,5 +1,5 @@
1
- PluginGeofencing_kotlinVersion=1.8.0
2
- PluginGeofencing_minSdkVersion=21
3
- PluginGeofencing_targetSdkVersion=35
4
- PluginGeofencing_compileSdkVersion=35
5
- PluginGeofencing_ndkversion=25.1.8937393
1
+ PluginGeofencing_kotlinVersion=2.1.20
2
+ PluginGeofencing_minSdkVersion=24
3
+ PluginGeofencing_targetSdkVersion=36
4
+ PluginGeofencing_compileSdkVersion=36
5
+ PluginGeofencing_ndkversion=27.1.12297006
@@ -70,14 +70,6 @@ public class PluginGeofencingModule extends ReactContextBaseJavaModule implement
70
70
  }
71
71
 
72
72
 
73
- // Example method
74
- // See https://reactnative.dev/docs/native-modules-android
75
- @ReactMethod
76
- public void multiply(int a, int b, Promise promise) {
77
- promise.resolve(a * b);
78
- }
79
-
80
-
81
73
  /***
82
74
  * Initializes Woosmap object with given parameters.
83
75
  * @param map ReadableMap may contain privateKeyWoosmapAPI with Woosmap API key,
@@ -468,6 +460,8 @@ public class PluginGeofencingModule extends ReactContextBaseJavaModule implement
468
460
  * @param data accepts Woosmap API key in a Readable array.
469
461
  * @param promise React native callback context.
470
462
  */
463
+ // implemented in turbo (WoosmapGeofencingTurbo)
464
+ @Deprecated
471
465
  @ReactMethod
472
466
  public void setWoosmapApiKey(ReadableArray data, Promise promise) {
473
467
  try {
@@ -682,6 +676,8 @@ public class PluginGeofencingModule extends ReactContextBaseJavaModule implement
682
676
  * @param radius A string containing POI radius value in number,string,double format.
683
677
  * @param promise React native callback context.
684
678
  */
679
+ // implemented in turbo (WoosmapGeofencingTurbo)
680
+ @Deprecated
685
681
  @ReactMethod
686
682
  public void setPoiRadius(String radius, Promise promise) {
687
683
  try {
@@ -741,6 +737,8 @@ public class PluginGeofencingModule extends ReactContextBaseJavaModule implement
741
737
  * @param map Readable map with region detail.
742
738
  * @param promise React native callback context.
743
739
  */
740
+ // implemented in turbo (WoosmapGeofencingTurbo)
741
+ @Deprecated
744
742
  @RequiresApi(api = Build.VERSION_CODES.N)
745
743
  @ReactMethod
746
744
  public void addRegion(ReadableMap map, Promise promise) {
@@ -772,6 +770,8 @@ public class PluginGeofencingModule extends ReactContextBaseJavaModule implement
772
770
  * @param regionid A string unique value for region.
773
771
  * @param promise React native callback context.
774
772
  */
773
+ // implemented in turbo (WoosmapGeofencingTurbo)
774
+ @Deprecated
775
775
  @RequiresApi(api = Build.VERSION_CODES.N)
776
776
  @ReactMethod
777
777
  public void getRegions(String regionid, Promise promise){
@@ -797,6 +797,8 @@ public class PluginGeofencingModule extends ReactContextBaseJavaModule implement
797
797
  * Gets all saved region from the database.
798
798
  * @param promise React native callback context.
799
799
  */
800
+ // implemented in turbo (WoosmapGeofencingTurbo — getRegions handles all + single)
801
+ @Deprecated
800
802
  @RequiresApi(api = Build.VERSION_CODES.N)
801
803
  @ReactMethod
802
804
  public void getAllRegions(Promise promise){
@@ -817,6 +819,8 @@ public class PluginGeofencingModule extends ReactContextBaseJavaModule implement
817
819
  * @param regionid A unique string region id which is to be removed.
818
820
  * @param promise React native callback context.
819
821
  */
822
+ // implemented in turbo (WoosmapGeofencingTurbo)
823
+ @Deprecated
820
824
  @RequiresApi(api = Build.VERSION_CODES.N)
821
825
  @ReactMethod
822
826
  private void removeRegion(String regionid, Promise promise){
@@ -840,6 +844,8 @@ public class PluginGeofencingModule extends ReactContextBaseJavaModule implement
840
844
  * Removes all region from saved database.
841
845
  * @param promise React native callback context.
842
846
  */
847
+ // implemented in turbo (WoosmapGeofencingTurbo)
848
+ @Deprecated
843
849
  @RequiresApi(api = Build.VERSION_CODES.N)
844
850
  @ReactMethod
845
851
  private void removeAllRegions(Promise promise){
@@ -0,0 +1,185 @@
1
+ package com.reactnativeplugingeofencing;
2
+
3
+ import android.os.Build;
4
+
5
+ import androidx.annotation.NonNull;
6
+ import androidx.annotation.Nullable;
7
+ import androidx.annotation.RequiresApi;
8
+
9
+ import com.facebook.react.bridge.Promise;
10
+ import com.facebook.react.bridge.ReactApplicationContext;
11
+ import com.facebook.react.bridge.ReadableMap;
12
+ import com.facebook.react.module.annotations.ReactModule;
13
+ import com.woosmap.reactnativeplugingeofencing.NativeWoosmapGeofencingTurboSpec;
14
+ import com.webgeoservices.woosmapgeofencing.Woosmap;
15
+ import com.webgeoservices.woosmapgeofencing.WoosmapSettings;
16
+ import com.webgeoservices.woosmapgeofencingcore.database.Region;
17
+
18
+ /**
19
+ * TurboModule implementation for the region-CRUD + key/radius slice migrated
20
+ * Extends the codegen-generated
21
+ * {@code NativeWoosmapGeofencingTurboSpec} abstract class.
22
+ *
23
+ * <p>This is a thin adapter over the shared {@link WoosmapTask} /
24
+ * {@link WoosmapSettings} layer — the same layer the legacy
25
+ * {@code PluginGeofencingModule} talks to — so the two modules stay
26
+ * independent without duplicating business logic. The SDK singleton
27
+ * ({@link Woosmap#getInstance()}) is shared, so a region added here lands in
28
+ * the same store that {@code initialize()} (still on the legacy module) set up.
29
+ */
30
+ @ReactModule(name = WoosmapGeofencingTurboModule.NAME)
31
+ public class WoosmapGeofencingTurboModule extends NativeWoosmapGeofencingTurboSpec {
32
+ public static final String NAME = "WoosmapGeofencingTurbo";
33
+
34
+ private final ReactApplicationContext reactContext;
35
+
36
+ public WoosmapGeofencingTurboModule(ReactApplicationContext reactContext) {
37
+ super(reactContext);
38
+ this.reactContext = reactContext;
39
+ }
40
+
41
+ @Override
42
+ @NonNull
43
+ public String getName() {
44
+ return NAME;
45
+ }
46
+
47
+ /**
48
+ * The Woosmap SDK is a process singleton initialised by the legacy module's
49
+ * {@code initialize()}. We can't see that module's private field, so we use
50
+ * the singleton's presence as the readiness proxy for this sprint.
51
+ */
52
+ private boolean isWoosmapInitialized() {
53
+ return Woosmap.getInstance() != null;
54
+ }
55
+
56
+ private boolean onlyContainsNumbers(String text) {
57
+ try {
58
+ Long.parseLong(text);
59
+ return true;
60
+ } catch (NumberFormatException ex) {
61
+ return false;
62
+ }
63
+ }
64
+
65
+ private boolean onlyContainsDouble(String text) {
66
+ try {
67
+ Double.parseDouble(text);
68
+ return true;
69
+ } catch (NumberFormatException ex) {
70
+ return false;
71
+ }
72
+ }
73
+
74
+ @Override
75
+ public void setWoosmapApiKey(String apiKey, Promise promise) {
76
+ try {
77
+ if (!isWoosmapInitialized()) {
78
+ promise.reject(WoosmapMessageAndKey.errorCode, WoosmapMessageAndKey.woosmapNotInitialized);
79
+ return;
80
+ }
81
+ if (apiKey == null || apiKey.isEmpty()) {
82
+ promise.reject(WoosmapMessageAndKey.errorCode, WoosmapMessageAndKey.woosmapKeyNotProvide);
83
+ return;
84
+ }
85
+ WoosmapSettings.privateKeyWoosmapAPI = apiKey;
86
+ promise.resolve(WoosmapMessageAndKey.successMessage);
87
+ } catch (Exception ex) {
88
+ promise.reject(WoosmapMessageAndKey.errorCode, ex.getMessage());
89
+ }
90
+ }
91
+
92
+ @Override
93
+ public void setPoiRadius(String radius, Promise promise) {
94
+ try {
95
+ if (!isWoosmapInitialized()) {
96
+ promise.reject(WoosmapMessageAndKey.errorCode, WoosmapMessageAndKey.woosmapNotInitialized);
97
+ return;
98
+ }
99
+ if (radius == null || radius.isEmpty()) {
100
+ throw new Exception(WoosmapMessageAndKey.radiusEmptyMessage);
101
+ }
102
+ if (onlyContainsNumbers(radius)) {
103
+ WoosmapSettings.poiRadius = Integer.parseInt(radius);
104
+ } else if (onlyContainsDouble(radius)) {
105
+ WoosmapSettings.poiRadius = (int) Math.round(Double.parseDouble(radius));
106
+ } else {
107
+ WoosmapSettings.poiRadiusNameFromResponse = radius;
108
+ }
109
+ promise.resolve(WoosmapMessageAndKey.successMessage);
110
+ } catch (Exception ex) {
111
+ promise.reject(WoosmapMessageAndKey.errorCode, ex.getMessage());
112
+ }
113
+ }
114
+
115
+ @RequiresApi(api = Build.VERSION_CODES.N)
116
+ @Override
117
+ public void addRegion(ReadableMap region, Promise promise) {
118
+ try {
119
+ if (!isWoosmapInitialized()) {
120
+ promise.reject(WoosmapMessageAndKey.errorCode, WoosmapMessageAndKey.woosmapNotInitialized);
121
+ return;
122
+ }
123
+ if (region == null || region.toHashMap().isEmpty()) {
124
+ throw new Exception(WoosmapMessageAndKey.regionInfoEmptyMessage);
125
+ }
126
+ Region woosRegion = new Region();
127
+ woosRegion.identifier = region.getString("regionId");
128
+ woosRegion.idStore = region.hasKey("idStore") ? region.getString("idStore") : "";
129
+ woosRegion.lat = region.getDouble("lat");
130
+ woosRegion.lng = region.getDouble("lng");
131
+ woosRegion.type = region.hasKey("type") ? region.getString("type") : "";
132
+ woosRegion.radius = region.getDouble("radius");
133
+
134
+ WoosmapTask.getInstance(reactContext).addRegion(woosRegion, promise);
135
+ } catch (Exception ex) {
136
+ promise.reject(WoosmapMessageAndKey.errorCode, ex.getMessage());
137
+ }
138
+ }
139
+
140
+ @RequiresApi(api = Build.VERSION_CODES.N)
141
+ @Override
142
+ public void getRegions(@Nullable String regionId, Promise promise) {
143
+ try {
144
+ if (!isWoosmapInitialized()) {
145
+ promise.reject(WoosmapMessageAndKey.errorCode, WoosmapMessageAndKey.woosmapNotInitialized);
146
+ return;
147
+ }
148
+ WoosmapTask.getInstance(reactContext).enqueGetRegionsAsArrayRequest(regionId, promise);
149
+ } catch (Exception ex) {
150
+ promise.reject(WoosmapMessageAndKey.errorCode, ex.getMessage());
151
+ }
152
+ }
153
+
154
+ @RequiresApi(api = Build.VERSION_CODES.N)
155
+ @Override
156
+ public void removeRegion(String regionId, Promise promise) {
157
+ try {
158
+ if (!isWoosmapInitialized()) {
159
+ promise.reject(WoosmapMessageAndKey.errorCode, WoosmapMessageAndKey.woosmapNotInitialized);
160
+ return;
161
+ }
162
+ if (regionId == null || regionId.isEmpty()) {
163
+ promise.reject(WoosmapMessageAndKey.errorCode, WoosmapMessageAndKey.requiredRegionid);
164
+ return;
165
+ }
166
+ WoosmapTask.getInstance(reactContext).removeRegion(regionId, promise);
167
+ } catch (Exception ex) {
168
+ promise.reject(WoosmapMessageAndKey.errorCode, ex.getMessage());
169
+ }
170
+ }
171
+
172
+ @RequiresApi(api = Build.VERSION_CODES.N)
173
+ @Override
174
+ public void removeAllRegions(Promise promise) {
175
+ try {
176
+ if (!isWoosmapInitialized()) {
177
+ promise.reject(WoosmapMessageAndKey.errorCode, WoosmapMessageAndKey.woosmapNotInitialized);
178
+ return;
179
+ }
180
+ WoosmapTask.getInstance(reactContext).removeRegion("", promise);
181
+ } catch (Exception ex) {
182
+ promise.reject(WoosmapMessageAndKey.errorCode, ex.getMessage());
183
+ }
184
+ }
185
+ }
@@ -0,0 +1,51 @@
1
+ package com.reactnativeplugingeofencing;
2
+
3
+ import androidx.annotation.Nullable;
4
+
5
+ import com.facebook.react.TurboReactPackage;
6
+ import com.facebook.react.bridge.NativeModule;
7
+ import com.facebook.react.bridge.ReactApplicationContext;
8
+ import com.facebook.react.module.model.ReactModuleInfo;
9
+ import com.facebook.react.module.model.ReactModuleInfoProvider;
10
+
11
+ import java.util.HashMap;
12
+ import java.util.Map;
13
+
14
+ /**
15
+ * TurboReactPackage that registers {@link WoosmapGeofencingTurboModule}.
16
+ *
17
+ * <p>Kept separate from {@code PluginGeofencingPackage} so the New-Architecture
18
+ * module and the legacy module load independently. To avoid the startup-race
19
+ * register this package <em>before</em> the legacy one
20
+ * in the host app's {@code MainApplication} package list.
21
+ */
22
+ public class WoosmapGeofencingTurboPackage extends TurboReactPackage {
23
+
24
+ @Nullable
25
+ @Override
26
+ public NativeModule getModule(String name, ReactApplicationContext reactContext) {
27
+ if (WoosmapGeofencingTurboModule.NAME.equals(name)) {
28
+ return new WoosmapGeofencingTurboModule(reactContext);
29
+ }
30
+ return null;
31
+ }
32
+
33
+ @Override
34
+ public ReactModuleInfoProvider getReactModuleInfoProvider() {
35
+ return () -> {
36
+ Map<String, ReactModuleInfo> moduleInfos = new HashMap<>();
37
+ moduleInfos.put(
38
+ WoosmapGeofencingTurboModule.NAME,
39
+ new ReactModuleInfo(
40
+ WoosmapGeofencingTurboModule.NAME,
41
+ WoosmapGeofencingTurboModule.NAME,
42
+ false, // canOverrideExistingModule
43
+ false, // needsEagerInit
44
+ false, // isCxxModule
45
+ true // isTurboModule
46
+ )
47
+ );
48
+ return moduleInfos;
49
+ };
50
+ }
51
+ }
@@ -117,6 +117,45 @@ public class WoosmapTask {
117
117
  }
118
118
  });
119
119
  }
120
+
121
+ /**
122
+ * Resolves regions as a {@link WritableArray} in all cases. Used by the
123
+ * WoosmapGeofencingTurbo module, whose getRegions spec always returns a
124
+ * collection (the legacy getRegions(id) resolved a single object instead).
125
+ * A null/empty regionID returns every saved region.
126
+ * @param regionID region id to fetch, or null/empty for all regions.
127
+ * @param promise React native callback context.
128
+ */
129
+ @RequiresApi(api = Build.VERSION_CODES.N)
130
+ public void enqueGetRegionsAsArrayRequest(String regionID, Promise promise) {
131
+ CompletableFuture.supplyAsync(() -> {
132
+ try {
133
+ WritableArray array = Arguments.createArray();
134
+ if (regionID == null || regionID.isEmpty()) {
135
+ Region[] regions = WoosmapDb.getInstance(context).getRegionsDAO().getAllRegions();
136
+ for (Region region : regions) {
137
+ array.pushMap(WoosmapUtil.getRegionWritableMap(region));
138
+ }
139
+ } else {
140
+ Region region = WoosmapDb.getInstance(context).getRegionsDAO().getRegionFromId(regionID);
141
+ if (region == null) {
142
+ throw new Exception(WoosmapMessageAndKey.invalidRegionid);
143
+ }
144
+ array.pushMap(WoosmapUtil.getRegionWritableMap(region));
145
+ }
146
+ return array;
147
+ } catch (Exception ex) {
148
+ throw new CompletionException(ex);
149
+ }
150
+ }).whenComplete((data, throwable) -> {
151
+ if (throwable == null) {
152
+ promise.resolve(data);
153
+ } else {
154
+ promise.reject(WoosmapMessageAndKey.errorCode, throwable.getMessage());
155
+ }
156
+ });
157
+ }
158
+
120
159
  @RequiresApi(api = Build.VERSION_CODES.N)
121
160
  public void removeRegion(String regionId, final Promise promise){
122
161
  CompletableFuture.supplyAsync((Supplier<Void>) () -> {
@@ -2,10 +2,6 @@
2
2
 
3
3
  @interface RCT_EXTERN_MODULE(PluginGeofencing, NSObject)
4
4
 
5
- RCT_EXTERN_METHOD(multiply:(float)a withB:(float)b
6
- withResolver:(RCTPromiseResolveBlock)resolve
7
- withRejecter:(RCTPromiseRejectBlock)reject)
8
-
9
5
  RCT_EXTERN_METHOD(initialize:(NSDictionary *)options
10
6
  withResolver:(RCTPromiseResolveBlock)resolve
11
7
  withRejecter:(RCTPromiseRejectBlock)reject)
@@ -69,12 +69,6 @@ class PluginGeofencing: RCTEventEmitter {
69
69
  return resultError
70
70
  }
71
71
 
72
- @objc(multiply:withB:withResolver:withRejecter:)
73
- func multiply(a: Float, b: Float, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
74
- resolve(a*b)
75
- }
76
-
77
-
78
72
  @objc(initialize:withResolver:withRejecter:)
79
73
  func initialize(command: NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void{
80
74
 
@@ -165,6 +159,8 @@ class PluginGeofencing: RCTEventEmitter {
165
159
 
166
160
  /// Updating new woosmap key
167
161
  /// - Parameter command: -
162
+ // implemented in turbo (WoosmapGeofencingTurbo)
163
+ @available(*, deprecated, message: "Implemented in the WoosmapGeofencingTurbo TurboModule")
168
164
  @objc(setWoosmapApiKey:withResolver:withRejecter:)
169
165
  func setWoosmapApiKey(command: NSArray, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void{
170
166
 
@@ -457,6 +453,8 @@ class PluginGeofencing: RCTEventEmitter {
457
453
  /// - regioninfo: regioninfo description
458
454
  /// - resolve: return Reference watchid on successfully call
459
455
  /// - reject: return error info
456
+ // implemented in turbo (WoosmapGeofencingTurbo)
457
+ @available(*, deprecated, message: "Implemented in the WoosmapGeofencingTurbo TurboModule")
460
458
  @objc(addRegion:withResolver:withRejecter:)
461
459
  func addRegion(regioninfo:NSDictionary, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) {
462
460
  if let woosService = WoosmapGeofenceService.shared {
@@ -570,6 +568,8 @@ class PluginGeofencing: RCTEventEmitter {
570
568
  /// - radius: radius enum or number in meters
571
569
  /// - resolve: return Ok on successfully call
572
570
  /// - reject: return error info
571
+ // implemented in turbo (WoosmapGeofencingTurbo)
572
+ @available(*, deprecated, message: "Implemented in the WoosmapGeofencingTurbo TurboModule")
573
573
  @objc(setPoiRadius:withResolver:withRejecter:)
574
574
  func setPoiRadius (radius: String, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) {
575
575
  if WoosmapGeofenceService.shared != nil {
@@ -604,6 +604,8 @@ class PluginGeofencing: RCTEventEmitter {
604
604
  /// - Parameters:
605
605
  /// - resolve: return list of Array with region info
606
606
  /// - reject: return error info
607
+ // implemented in turbo (WoosmapGeofencingTurbo — getRegions handles all + single)
608
+ @available(*, deprecated, message: "Implemented in the WoosmapGeofencingTurbo TurboModule")
607
609
  @objc(getAllRegions:withRejecter:)
608
610
  func getAllRegions(resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) {
609
611
  if let objWoos = WoosmapGeofenceService.shared {
@@ -626,6 +628,8 @@ class PluginGeofencing: RCTEventEmitter {
626
628
  /// - regionid: regionid to fetch
627
629
  /// - resolve: return region info
628
630
  /// - reject: error info
631
+ // implemented in turbo (WoosmapGeofencingTurbo)
632
+ @available(*, deprecated, message: "Implemented in the WoosmapGeofencingTurbo TurboModule")
629
633
  @objc(getRegions:withResolver:withRejecter:)
630
634
  func getRegions(regionid:String, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) {
631
635
  if let objWoos = WoosmapGeofenceService.shared {
@@ -656,6 +660,8 @@ class PluginGeofencing: RCTEventEmitter {
656
660
  /// - Parameters:
657
661
  /// - resolve: return regionDeleted
658
662
  /// - reject: error info
663
+ // implemented in turbo (WoosmapGeofencingTurbo)
664
+ @available(*, deprecated, message: "Implemented in the WoosmapGeofencingTurbo TurboModule")
659
665
  @objc(removeAllRegions:withRejecter:)
660
666
  func removeAllRegions(resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) {
661
667
  if let objWoos = WoosmapGeofenceService.shared {
@@ -673,6 +679,8 @@ class PluginGeofencing: RCTEventEmitter {
673
679
  /// - regionid: region id
674
680
  /// - resolve: return regionDeleted
675
681
  /// - reject: error info
682
+ // implemented in turbo (WoosmapGeofencingTurbo)
683
+ @available(*, deprecated, message: "Implemented in the WoosmapGeofencingTurbo TurboModule")
676
684
  @objc(removeRegion:withResolver:withRejecter:)
677
685
  func removeRegion(regionid:String, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) {
678
686
  if let objWoos = WoosmapGeofenceService.shared {
@@ -247,8 +247,12 @@ extension CLRegion {
247
247
  airshipTrackingEnable: Bool = false,
248
248
  protectedRegionSlot: Int = -1
249
249
  ) {
250
- //TODO: Check This
251
- Task { @MainActor in
250
+ // Initialize synchronously so the native module's `initialize` promise
251
+ // does not resolve before `_shared` has actually been assigned.
252
+ // Native module methods run on a background dispatch queue, so we hop to
253
+ // the main thread (where `WoosmapGeofenceService.init` is MainActor-isolated)
254
+ // and block until the assignment completes.
255
+ runOnMainSync {
252
256
  _shared = WoosmapGeofenceService.init(
253
257
  woosmapKey,
254
258
  configurationProfile,
@@ -260,12 +264,25 @@ extension CLRegion {
260
264
 
261
265
  /// Creating instance for woosGeofencing service
262
266
  @objc public static func setup() {
263
- //TODO: Check This
264
- Task { @MainActor in
267
+ runOnMainSync {
265
268
  _shared = WoosmapGeofenceService.init("", "")
266
269
  }
267
270
  }
268
271
 
272
+ /// Runs the given MainActor-isolated work synchronously, dispatching to the
273
+ /// main thread when called from a background queue. Safe to call from either
274
+ /// the main thread or any other thread — avoids the `DispatchQueue.main.sync`
275
+ /// deadlock when already on main.
276
+ private static func runOnMainSync(_ work: @MainActor () -> Void) {
277
+ if Thread.isMainThread {
278
+ MainActor.assumeIsolated { work() }
279
+ } else {
280
+ DispatchQueue.main.sync {
281
+ MainActor.assumeIsolated { work() }
282
+ }
283
+ }
284
+ }
285
+
269
286
  /// Setting up woosmap key
270
287
  /// - Parameter key: woosmap key
271
288
  /// - Throws: WoosGeofenceError incase of no key pass or empty
@@ -0,0 +1,66 @@
1
+ #import <React/RCTBridgeModule.h>
2
+
3
+ #ifdef RCT_NEW_ARCH_ENABLED
4
+ // Generated by codegen from src/NativeWoosmapGeofencingTurbo.ts via the
5
+ // `WoosmapGeofencingTurboSpec` codegenConfig entry in package.json. Provides
6
+ // the RCTNativeWoosmapGeofencingTurboSpec protocol and the
7
+ // NativeWoosmapGeofencingTurboSpecJSI C++ TurboModule.
8
+ #import <WoosmapGeofencingTurboSpec/WoosmapGeofencingTurboSpec.h>
9
+ #endif
10
+
11
+ // Bridges the Swift `WoosmapGeofencingTurbo` implementation to React Native.
12
+ // The selectors below must match the @objc(...) selectors declared in
13
+ // WoosmapGeofencingTurbo.swift.
14
+ @interface RCT_EXTERN_MODULE(WoosmapGeofencingTurbo, NSObject)
15
+
16
+ // Selectors follow the React Native codegen Promise convention
17
+ // (`<method>:resolve:reject:`, or `<method>:reject:` for no-arg methods) so the
18
+ // generated NativeWoosmapGeofencingTurboSpecJSI bindings dispatch correctly.
19
+ RCT_EXTERN_METHOD(setWoosmapApiKey:(NSString *)apiKey
20
+ resolve:(RCTPromiseResolveBlock)resolve
21
+ reject:(RCTPromiseRejectBlock)reject)
22
+
23
+ RCT_EXTERN_METHOD(setPoiRadius:(NSString *)radius
24
+ resolve:(RCTPromiseResolveBlock)resolve
25
+ reject:(RCTPromiseRejectBlock)reject)
26
+
27
+ RCT_EXTERN_METHOD(addRegion:(NSDictionary *)region
28
+ resolve:(RCTPromiseResolveBlock)resolve
29
+ reject:(RCTPromiseRejectBlock)reject)
30
+
31
+ RCT_EXTERN_METHOD(getRegions:(NSString *)regionId
32
+ resolve:(RCTPromiseResolveBlock)resolve
33
+ reject:(RCTPromiseRejectBlock)reject)
34
+
35
+ RCT_EXTERN_METHOD(removeAllRegions:(RCTPromiseResolveBlock)resolve
36
+ reject:(RCTPromiseRejectBlock)reject)
37
+
38
+ RCT_EXTERN_METHOD(removeRegion:(NSString *)regionId
39
+ resolve:(RCTPromiseResolveBlock)resolve
40
+ reject:(RCTPromiseRejectBlock)reject)
41
+
42
+ + (BOOL)requiresMainQueueSetup
43
+ {
44
+ return YES;
45
+ }
46
+
47
+ @end
48
+
49
+ #ifdef RCT_NEW_ARCH_ENABLED
50
+ // Vends the JSI TurboModule so the 6 methods dispatch through the generated
51
+ // codegen path (no ObjCTurboModule reflection fallback). Implemented as a
52
+ // category on the Swift class because getTurboModule: returns a C++ type that
53
+ // cannot be expressed in Swift.
54
+ @interface WoosmapGeofencingTurbo (TurboModule) <RCTTurboModule>
55
+ @end
56
+
57
+ @implementation WoosmapGeofencingTurbo (TurboModule)
58
+
59
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
60
+ (const facebook::react::ObjCTurboModule::InitParams &)params
61
+ {
62
+ return std::make_shared<facebook::react::NativeWoosmapGeofencingTurboSpecJSI>(params);
63
+ }
64
+
65
+ @end
66
+ #endif