@sodyo/react-native-sodyo-sdk 5.0.2 → 5.1.0

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.
@@ -75,6 +75,13 @@ public class RNSodyoSdkModule extends ReactContextBaseJavaModule {
75
75
  this.reactContext.addActivityEventListener(mActivityEventListener);
76
76
  }
77
77
 
78
+ // Issue #4 fix: remove listener on destroy to prevent leak
79
+ @Override
80
+ public void onCatalystInstanceDestroy() {
81
+ super.onCatalystInstanceDestroy();
82
+ reactContext.removeActivityEventListener(mActivityEventListener);
83
+ }
84
+
78
85
  @Override
79
86
  public String getName() {
80
87
  return "RNSodyoSdk";
@@ -205,12 +212,16 @@ public class RNSodyoSdkModule extends ReactContextBaseJavaModule {
205
212
  }
206
213
  }
207
214
 
215
+ // Issue #7 fix: invoke success callback if already initialized
208
216
  @ReactMethod
209
217
  public void init(final String apiKey, Callback successCallback, Callback errorCallback) {
210
218
  Log.i(TAG, "init()");
211
219
 
212
220
  if (Sodyo.isInitialized()) {
213
- Log.i(TAG, "init(): already initialized, ignore");
221
+ Log.i(TAG, "init(): already initialized");
222
+ if (successCallback != null) {
223
+ successCallback.invoke();
224
+ }
214
225
  return;
215
226
  }
216
227
 
@@ -228,11 +239,16 @@ public class RNSodyoSdkModule extends ReactContextBaseJavaModule {
228
239
  });
229
240
  }
230
241
 
242
+ // Issue #1 fix: null-check getCurrentActivity()
231
243
  @ReactMethod
232
244
  public void start() {
233
245
  Log.i(TAG, "start()");
234
- Intent intent = new Intent(this.reactContext, SodyoScannerActivity.class);
235
246
  Activity activity = getCurrentActivity();
247
+ if (activity == null) {
248
+ Log.e(TAG, "start(): current activity is null");
249
+ return;
250
+ }
251
+ Intent intent = new Intent(activity, SodyoScannerActivity.class);
236
252
  activity.startActivityForResult(intent, SODYO_SCANNER_REQUEST_CODE);
237
253
  }
238
254
 
@@ -240,13 +256,23 @@ public class RNSodyoSdkModule extends ReactContextBaseJavaModule {
240
256
  public void close() {
241
257
  Log.i(TAG, "close()");
242
258
  Activity activity = getCurrentActivity();
259
+ if (activity == null) {
260
+ Log.e(TAG, "close(): current activity is null");
261
+ return;
262
+ }
243
263
  activity.finishActivity(SODYO_SCANNER_REQUEST_CODE);
244
264
  }
245
265
 
266
+ // Issue #6 fix: guard against uninitialized SDK
246
267
  @ReactMethod
247
268
  public void setUserInfo(ReadableMap userInfo) {
248
269
  Log.i(TAG, "setUserInfo()");
249
270
 
271
+ if (!Sodyo.isInitialized()) {
272
+ Log.w(TAG, "setUserInfo(): SDK not initialized yet");
273
+ return;
274
+ }
275
+
250
276
  if(userInfo != null) {
251
277
  Sodyo.getInstance().setUserInfo(ConversionUtil.toMap(userInfo));
252
278
  }
@@ -307,6 +333,10 @@ public class RNSodyoSdkModule extends ReactContextBaseJavaModule {
307
333
  public void performMarker(String markerId, ReadableMap customProperties) {
308
334
  Log.i(TAG, "performMarker()");
309
335
  Activity activity = getCurrentActivity();
336
+ if (activity == null) {
337
+ Log.e(TAG, "performMarker(): current activity is null");
338
+ return;
339
+ }
310
340
  Sodyo.performMarker(markerId, activity, ConversionUtil.toMap(customProperties));
311
341
  }
312
342
 
@@ -314,6 +344,10 @@ public class RNSodyoSdkModule extends ReactContextBaseJavaModule {
314
344
  public void startTroubleshoot() {
315
345
  Log.i(TAG, "startTroubleshoot()");
316
346
  Activity activity = getCurrentActivity();
347
+ if (activity == null) {
348
+ Log.e(TAG, "startTroubleshoot(): current activity is null");
349
+ return;
350
+ }
317
351
  Sodyo.startTroubleshoot(activity);
318
352
  }
319
353
 
@@ -321,6 +355,10 @@ public class RNSodyoSdkModule extends ReactContextBaseJavaModule {
321
355
  public void setTroubleshootMode() {
322
356
  Log.i(TAG, "setTroubleshootMode()");
323
357
  Activity activity = getCurrentActivity();
358
+ if (activity == null) {
359
+ Log.e(TAG, "setTroubleshootMode(): current activity is null");
360
+ return;
361
+ }
324
362
  Sodyo.setMode(activity, SettingsHelper.ScannerViewMode.Troubleshoot);
325
363
  }
326
364
 
@@ -328,6 +366,10 @@ public class RNSodyoSdkModule extends ReactContextBaseJavaModule {
328
366
  public void setNormalMode() {
329
367
  Log.i(TAG, "setNormalMode()");
330
368
  Activity activity = getCurrentActivity();
369
+ if (activity == null) {
370
+ Log.e(TAG, "setNormalMode(): current activity is null");
371
+ return;
372
+ }
331
373
  Sodyo.setMode(activity, SettingsHelper.ScannerViewMode.Normal);
332
374
  }
333
375
 
@@ -342,20 +384,34 @@ public class RNSodyoSdkModule extends ReactContextBaseJavaModule {
342
384
  Sodyo.setSodyoLogoVisible(isVisible);
343
385
  }
344
386
 
387
+ // Issue #2 fix: validate env input, Issue #10 fix: public instead of private
345
388
  @ReactMethod
346
- private void setEnv(String env) {
389
+ public void setEnv(String env) {
347
390
  Log.i(TAG, "setEnv:" + env);
348
391
 
349
- Map<String, String> params = new HashMap<>();
350
- String value = String.valueOf(SodyoEnv.valueOf(env.trim().toUpperCase()).getValue());
351
- params.put("webad_env", value);
352
- params.put("scanner_QR_code_enabled", "false");
353
- Sodyo.setScannerParams(params);
392
+ if (env == null) {
393
+ Log.e(TAG, "setEnv: env is null");
394
+ return;
395
+ }
396
+
397
+ try {
398
+ SodyoEnv sodyoEnv = SodyoEnv.valueOf(env.trim().toUpperCase());
399
+ Map<String, String> params = new HashMap<>();
400
+ params.put("webad_env", String.valueOf(sodyoEnv.getValue()));
401
+ params.put("scanner_QR_code_enabled", "false");
402
+ Sodyo.setScannerParams(params);
403
+ } catch (IllegalArgumentException e) {
404
+ Log.e(TAG, "setEnv: unknown env '" + env + "', expected DEV/QA/PROD");
405
+ }
354
406
  }
355
407
 
408
+ // Issue #12 fix: check for active React instance before sending events
356
409
  private void sendEvent(String eventName, @Nullable WritableMap params) {
357
- this.reactContext
410
+ if (!reactContext.hasActiveReactInstance()) {
411
+ return;
412
+ }
413
+ reactContext
358
414
  .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
359
415
  .emit(eventName, params);
360
416
  }
361
- }
417
+ }
@@ -81,11 +81,14 @@ public class RNSodyoSdkView extends SimpleViewManager<FrameLayout> {
81
81
  isCameraEnabled = true;
82
82
 
83
83
  try {
84
- FragmentManager fragmentManager = mCallerContext.getCurrentActivity().getFragmentManager();
85
- Fragment fragment = fragmentManager.findFragmentByTag(TAG_FRAGMENT);
86
-
87
- if (fragment != null) {
88
- fragmentManager.beginTransaction().remove(fragment).commitNowAllowingStateLoss();
84
+ Activity currentActivity = mCallerContext.getCurrentActivity();
85
+ if (currentActivity != null) {
86
+ FragmentManager fragmentManager = currentActivity.getFragmentManager();
87
+ Fragment fragment = fragmentManager.findFragmentByTag(TAG_FRAGMENT);
88
+
89
+ if (fragment != null) {
90
+ fragmentManager.beginTransaction().remove(fragment).commitNowAllowingStateLoss();
91
+ }
89
92
  }
90
93
  } catch (Exception e) {
91
94
  e.printStackTrace();
@@ -110,4 +113,4 @@ public class RNSodyoSdkView extends SimpleViewManager<FrameLayout> {
110
113
  sodyoFragment.stopCamera();
111
114
  }
112
115
  }
113
- }
116
+ }
@@ -0,0 +1,360 @@
1
+ # iOS RNSodyoSdk Code Analysis
2
+
3
+ ## Summary
4
+
5
+ Analysis of all iOS source files in the `react-native-sodyo-sdk` bridge layer. Found **5 critical**, **4 major**, and **5 minor** issues across 6 files.
6
+
7
+ ---
8
+
9
+ ## Critical Issues
10
+
11
+ ### 1. Static Variable in Header File — Duplicate Symbol / Undefined Behavior
12
+
13
+ **File:** `RNSodyoScanner.h:14`
14
+
15
+ ```objc
16
+ static UIViewController* sodyoScanner = nil;
17
+ ```
18
+
19
+ A `static` variable in a header creates a **separate copy** in every `.m` file that imports it. `RNSodyoSdk.m`, `RNSodyoSdkManager.m`, and `RNSodyoScanner.m` each get their own independent `sodyoScanner`. This means:
20
+
21
+ - `RNSodyoSdkManager` sets `sodyoScanner` via `[RNSodyoScanner setSodyoScanner:]`, but that only updates the copy inside `RNSodyoScanner.m`.
22
+ - `RNSodyoSdk.m` reads its **own local copy** (`sodyoScanner`) which is always `nil` unless assigned directly in that file.
23
+ - `startTroubleshoot` at line 104 uses the local `sodyoScanner` which may be `nil`, causing a silent no-op or crash.
24
+
25
+ **Severity:** Critical — scanner functionality silently broken across modules.
26
+
27
+ **Fix:** Remove the `static` variable from the header. Use the `RNSodyoScanner` class methods exclusively:
28
+
29
+ ```objc
30
+ // RNSodyoScanner.h — remove line 14 entirely
31
+ // RNSodyoScanner.m — store the scanner as a class-level static
32
+ static UIViewController* _sharedScanner = nil;
33
+
34
+ @implementation RNSodyoScanner
35
+ + (UIViewController *)getSodyoScanner { return _sharedScanner; }
36
+ + (void)setSodyoScanner:(UIViewController *)scanner { _sharedScanner = scanner; }
37
+ @end
38
+ ```
39
+
40
+ Then in `RNSodyoSdk.m`, replace all bare `sodyoScanner` references with `[RNSodyoScanner getSodyoScanner]`.
41
+
42
+ ---
43
+
44
+ ### 2. Inverted Null-Check Logic — Scanner Never Saved
45
+
46
+ **File:** `RNSodyoSdk.m:153-155`
47
+
48
+ ```objc
49
+ if (!sodyoScanner) {
50
+ [RNSodyoScanner setSodyoScanner:sodyoScanner]; // saves nil
51
+ }
52
+ ```
53
+
54
+ This is inverted. It saves the scanner only when it's `nil`, which stores `nil` into the shared singleton. When `sodyoScanner` is non-nil, it's never persisted.
55
+
56
+ **Severity:** Critical — the scanner reference is never properly shared.
57
+
58
+ **Fix:**
59
+
60
+ ```objc
61
+ if (sodyoScanner) {
62
+ [RNSodyoScanner setSodyoScanner:sodyoScanner];
63
+ }
64
+ ```
65
+
66
+ Or better, always assign and let the setter handle dedup (it already does).
67
+
68
+ ---
69
+
70
+ ### 3. `BOOL *` (Pointer) Instead of `BOOL` — Always Truthy
71
+
72
+ **File:** `RNSodyoSdk.m:124`
73
+
74
+ ```objc
75
+ RCT_EXPORT_METHOD(setSodyoLogoVisible:(BOOL *) isVisible)
76
+ ```
77
+
78
+ `BOOL *` is a pointer-to-BOOL, not a BOOL. React Native will pass a non-null pointer, so the `if (isVisible)` check at line 127 always evaluates to `true` (non-null pointer), making `hideDefaultOverlay` unreachable.
79
+
80
+ **Severity:** Critical — logo can never be hidden from JS.
81
+
82
+ **Fix:**
83
+
84
+ ```objc
85
+ RCT_EXPORT_METHOD(setSodyoLogoVisible:(BOOL) isVisible)
86
+ ```
87
+
88
+ ---
89
+
90
+ ### 4. NSNotificationCenter Observer Never Removed — Memory Leak
91
+
92
+ **File:** `RNSodyoSdk.m:35`
93
+
94
+ ```objc
95
+ [[NSNotificationCenter defaultCenter] addObserver:self
96
+ selector:@selector(sendCloseContentEvent)
97
+ name:@"SodyoNotificationCloseIAD" object:nil];
98
+ ```
99
+
100
+ The observer is added but never removed. Since `NSNotificationCenter` holds an **unsafe unretained reference** (pre-iOS 9 behavior on block-based API, and always for selector-based), this can:
101
+
102
+ - Cause **crashes** if the module is deallocated while notifications fire.
103
+ - Cause **duplicate event delivery** if `createCloseContentListener` semantics change.
104
+
105
+ **Severity:** Critical — potential crash on deallocation.
106
+
107
+ **Fix:** Add a `dealloc` method:
108
+
109
+ ```objc
110
+ - (void)dealloc {
111
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
112
+ }
113
+ ```
114
+
115
+ ---
116
+
117
+ ### 5. Callback Retain Cycle — Blocks Held Indefinitely
118
+
119
+ **File:** `RNSodyoSdk.m:21-22`, `RNSodyoSdk.h:22-23`
120
+
121
+ ```objc
122
+ @property (nonatomic, strong) RCTResponseSenderBlock successStartCallback;
123
+ @property (nonatomic, strong) RCTResponseSenderBlock errorStartCallback;
124
+ ```
125
+
126
+ These blocks are stored as `strong` properties. If `onSodyoAppLoadSuccess` is called, `errorStartCallback` is **never nilled out** (and vice versa). The unused callback retains captured JS context forever.
127
+
128
+ Additionally, if `init:` is called multiple times, the previous callbacks are silently overwritten and leaked.
129
+
130
+ **Severity:** Critical — memory leak of JS bridge context.
131
+
132
+ **Fix:** Nil both callbacks after either fires:
133
+
134
+ ```objc
135
+ - (void)onSodyoAppLoadSuccess:(NSInteger)AppID {
136
+ if (self.successStartCallback) {
137
+ self.successStartCallback(@[[NSNull null]]);
138
+ }
139
+ self.successStartCallback = nil;
140
+ self.errorStartCallback = nil; // release the other one too
141
+ }
142
+
143
+ - (void)onSodyoAppLoadFailed:(NSInteger)AppID error:(NSError *)error {
144
+ if (self.errorStartCallback) {
145
+ self.errorStartCallback(@[@{@"error": error.localizedDescription ?: @"Unknown error"}]);
146
+ }
147
+ self.successStartCallback = nil; // release the other one too
148
+ self.errorStartCallback = nil;
149
+ }
150
+ ```
151
+
152
+ ---
153
+
154
+ ## Major Issues
155
+
156
+ ### 6. NSError Passed Directly to JS — Crash Risk
157
+
158
+ **File:** `RNSodyoSdk.m:203`
159
+
160
+ ```objc
161
+ self.errorStartCallback(@[@{@"error": error}]);
162
+ ```
163
+
164
+ `NSError` is not JSON-serializable. React Native's bridge expects serializable types. This will throw an exception or produce undefined behavior.
165
+
166
+ **Severity:** Major — crash when SDK load fails.
167
+
168
+ **Fix:**
169
+
170
+ ```objc
171
+ NSString *message = error.localizedDescription ?: @"Unknown error";
172
+ self.errorStartCallback(@[@{@"error": message}]);
173
+ ```
174
+
175
+ ---
176
+
177
+ ### 7. Nil Dictionary Value Crash in `sodyoError:`
178
+
179
+ **File:** `RNSodyoSdk.m:211`
180
+
181
+ ```objc
182
+ NSArray* params = @[@"sodyoError", error.userInfo[@"NSLocalizedDescription"]];
183
+ [self sendEventWithName:@"EventSodyoError" body:@{@"error": params[1]}];
184
+ ```
185
+
186
+ If `error.userInfo[@"NSLocalizedDescription"]` is `nil`, creating the `NSArray` literal crashes with `NSInvalidArgumentException` (nil inserted into immutable array).
187
+
188
+ **Severity:** Major — crash on certain error types.
189
+
190
+ **Fix:**
191
+
192
+ ```objc
193
+ NSString *desc = error.localizedDescription ?: @"Unknown error";
194
+ [self sendEventWithName:@"EventSodyoError" body:@{@"error": desc}];
195
+ ```
196
+
197
+ ---
198
+
199
+ ### 8. Nil Dictionary Value Crash in `setEnv:`
200
+
201
+ **File:** `RNSodyoSdk.m:138-139`
202
+
203
+ ```objc
204
+ NSDictionary *envs = @{ @"DEV": @"3", @"QA": @"1", @"PROD": @"0" };
205
+ NSDictionary *params = @{ @"SodyoAdEnv" : envs[env], @"ScanQR": @"false" };
206
+ ```
207
+
208
+ If `env` is not one of `DEV`, `QA`, `PROD`, then `envs[env]` returns `nil`. Inserting `nil` into an `NSDictionary` literal crashes.
209
+
210
+ **Severity:** Major — crash on invalid env string from JS.
211
+
212
+ **Fix:**
213
+
214
+ ```objc
215
+ NSString *envValue = envs[env];
216
+ if (!envValue) {
217
+ NSLog(@"RNSodyoSdk: Unknown env '%@', defaulting to PROD", env);
218
+ envValue = @"0";
219
+ }
220
+ NSDictionary *params = @{ @"SodyoAdEnv": envValue, @"ScanQR": @"false" };
221
+ ```
222
+
223
+ ---
224
+
225
+ ### 9. Nil Value Crash in `SodyoMarkerDetectedWithData:`
226
+
227
+ **File:** `RNSodyoSdk.m:218`
228
+
229
+ ```objc
230
+ [self sendEventWithName:@"EventMarkerDetectSuccess" body:@{@"data": Data[@"sodyoMarkerData"]}];
231
+ ```
232
+
233
+ If `Data` is `nil` or `Data[@"sodyoMarkerData"]` is `nil`, creating the dictionary literal crashes.
234
+
235
+ **Severity:** Major — crash when marker data is missing.
236
+
237
+ **Fix:**
238
+
239
+ ```objc
240
+ id markerData = Data[@"sodyoMarkerData"] ?: [NSNull null];
241
+ [self sendEventWithName:@"EventMarkerDetectSuccess" body:@{@"data": markerData}];
242
+ ```
243
+
244
+ Apply the same pattern to `SodyoMarkerContent:Data:` at line 223.
245
+
246
+ ---
247
+
248
+ ## Minor Issues
249
+
250
+ ### 10. Method Named `init:` Shadows NSObject
251
+
252
+ **File:** `RNSodyoSdk.m:14`
253
+
254
+ ```objc
255
+ RCT_EXPORT_METHOD(init:(NSString *)apiKey ...)
256
+ ```
257
+
258
+ While RCT_EXPORT_METHOD creates a different Objective-C selector internally, naming the JS method `init` is confusing and risks future collision with `NSObject`'s `init` family. Static analyzers may flag this.
259
+
260
+ **Fix:** Rename to `initialize:` or `setup:` on the native side, or document the JS-side name mapping.
261
+
262
+ ---
263
+
264
+ ### 11. Deprecated `window` Access Pattern
265
+
266
+ **File:** `RNSodyoSdk.m:95,162,170` and `RNSodyoSdkManager.m:63`
267
+
268
+ ```objc
269
+ UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
270
+ ```
271
+
272
+ `UIApplicationDelegate.window` is deprecated in iOS 15+ with UIScene. On apps using scenes, this returns `nil`, breaking all scanner presentation.
273
+
274
+ **Fix:** Use the key window from connected scenes:
275
+
276
+ ```objc
277
+ UIWindow *keyWindow = nil;
278
+ for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) {
279
+ if (scene.activationState == UISceneActivationStateForegroundActive) {
280
+ for (UIWindow *window in scene.windows) {
281
+ if (window.isKeyWindow) {
282
+ keyWindow = window;
283
+ break;
284
+ }
285
+ }
286
+ }
287
+ }
288
+ UIViewController *rootViewController = keyWindow.rootViewController;
289
+ ```
290
+
291
+ ---
292
+
293
+ ### 12. Child View Controller Not Removed on Cleanup
294
+
295
+ **File:** `RNSodyoSdkManager.m:68`
296
+
297
+ ```objc
298
+ [rootViewController addChildViewController:sodyoScanner];
299
+ ```
300
+
301
+ The scanner is added as a child view controller but never removed via `removeFromParentViewController` when the React view is unmounted. This leaks the child VC relationship.
302
+
303
+ **Fix:** Override cleanup in `RNSodyoSdkView` or the manager to call `[sodyoScanner removeFromParentViewController]`.
304
+
305
+ ---
306
+
307
+ ### 13. `isTroubleShootingEnabled` Has No `false` Handler
308
+
309
+ **File:** `RNSodyoSdkManager.m:45-59`
310
+
311
+ ```objc
312
+ if ([RCTConvert BOOL:json]) {
313
+ [SodyoSDK startTroubleshoot:sodyoScanner];
314
+ return;
315
+ }
316
+ // nothing happens when false
317
+ ```
318
+
319
+ Setting `isTroubleShootingEnabled={false}` is a no-op. There's no call to stop troubleshooting.
320
+
321
+ **Fix:** Add the false branch, e.g., `[SodyoSDK setMode:sodyoScanner mode:SodyoModeNormal]`.
322
+
323
+ ---
324
+
325
+ ### 14. Excessive `NSLog` in Production
326
+
327
+ **Files:** All `.m` files
328
+
329
+ Every method logs via `NSLog`, which writes to the system log in production builds. This is a minor performance issue and exposes internal method names.
330
+
331
+ **Fix:** Replace with `RCTLogInfo` (already used in one place) or wrap in `#ifdef DEBUG`:
332
+
333
+ ```objc
334
+ #ifdef DEBUG
335
+ #define SDLog(...) NSLog(__VA_ARGS__)
336
+ #else
337
+ #define SDLog(...) ((void)0)
338
+ #endif
339
+ ```
340
+
341
+ ---
342
+
343
+ ## Issue Summary Table
344
+
345
+ | # | Severity | File | Line | Issue |
346
+ |---|----------|------|------|-------|
347
+ | 1 | Critical | RNSodyoScanner.h | 14 | Static var in header — separate copies per file |
348
+ | 2 | Critical | RNSodyoSdk.m | 153 | Inverted null-check — scanner never saved |
349
+ | 3 | Critical | RNSodyoSdk.m | 124 | `BOOL *` instead of `BOOL` — always truthy |
350
+ | 4 | Critical | RNSodyoSdk.m | 35 | NSNotification observer never removed |
351
+ | 5 | Critical | RNSodyoSdk.m | 21-22 | Callback retain cycle — unused block never nilled |
352
+ | 6 | Major | RNSodyoSdk.m | 203 | NSError sent to JS — not serializable |
353
+ | 7 | Major | RNSodyoSdk.m | 211 | Nil value in array literal — crash |
354
+ | 8 | Major | RNSodyoSdk.m | 139 | Nil value in dict literal — crash on bad env |
355
+ | 9 | Major | RNSodyoSdk.m | 218 | Nil marker data — crash |
356
+ | 10 | Minor | RNSodyoSdk.m | 14 | Method named `init:` shadows NSObject |
357
+ | 11 | Minor | Multiple | — | Deprecated `window` access (iOS 15+) |
358
+ | 12 | Minor | RNSodyoSdkManager.m | 68 | Child VC never removed |
359
+ | 13 | Minor | RNSodyoSdkManager.m | 55 | No false-branch for troubleshooting toggle |
360
+ | 14 | Minor | All files | — | Excessive NSLog in production |
@@ -8,12 +8,11 @@
8
8
  #ifndef RNSodyoScanner_h
9
9
  #define RNSodyoScanner_h
10
10
 
11
-
12
- #endif /* RNSodyoScanner_h */
13
-
14
- static UIViewController* sodyoScanner = nil;
11
+ #import <UIKit/UIKit.h>
15
12
 
16
13
  @interface RNSodyoScanner : NSObject
17
14
  + (UIViewController *)getSodyoScanner;
18
15
  + (void)setSodyoScanner:(UIViewController *)sodyoScanner;
19
16
  @end
17
+
18
+ #endif /* RNSodyoScanner_h */
@@ -7,17 +7,18 @@
7
7
  #import "RNSodyoScanner.h"
8
8
  #import <Foundation/Foundation.h>
9
9
 
10
+ static UIViewController* _sharedScanner = nil;
11
+
10
12
  @implementation RNSodyoScanner
11
13
 
12
14
  + (UIViewController *) getSodyoScanner {
13
- return sodyoScanner;
15
+ return _sharedScanner;
14
16
  }
15
17
 
16
18
  + (void) setSodyoScanner:(UIViewController*) newSodyoScanner {
17
- if(sodyoScanner != newSodyoScanner) {
18
- sodyoScanner = newSodyoScanner;
19
+ if(_sharedScanner != newSodyoScanner) {
20
+ _sharedScanner = newSodyoScanner;
19
21
  }
20
22
  }
21
23
 
22
- @end
23
- // implementation of getter and setter
24
+ @end
package/ios/RNSodyoSdk.h CHANGED
@@ -15,9 +15,7 @@
15
15
  #import "SodyoSDK.h"
16
16
  #endif
17
17
 
18
- @interface RNSodyoSdk : RCTEventEmitter <RCTBridgeModule, SodyoSDKDelegate, SodyoMarkerDelegate> {
19
- UIViewController *sodyoScanner;
20
- }
18
+ @interface RNSodyoSdk : RCTEventEmitter <RCTBridgeModule, SodyoSDKDelegate, SodyoMarkerDelegate>
21
19
 
22
20
  @property (nonatomic, strong) RCTResponseSenderBlock successStartCallback;
23
21
  @property (nonatomic, strong) RCTResponseSenderBlock errorStartCallback;