@cleanuidev/react-native-scanner 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/LICENSE +20 -0
- package/README.md +609 -0
- package/Scanner.podspec +20 -0
- package/android/build.gradle +90 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +8 -0
- package/android/src/main/java/com/scanner/CameraInfoModule.kt +253 -0
- package/android/src/main/java/com/scanner/ScannerPackage.kt +21 -0
- package/android/src/main/java/com/scanner/ScannerView.kt +783 -0
- package/android/src/main/java/com/scanner/ScannerViewManager.kt +181 -0
- package/android/src/main/java/com/scanner/utils/BarcodeFrameManager.kt +170 -0
- package/android/src/main/java/com/scanner/views/BarcodeFrameOverlayView.kt +43 -0
- package/android/src/main/java/com/scanner/views/FocusAreaView.kt +124 -0
- package/ios/BarcodeDetectionManager.swift +229 -0
- package/ios/BarcodeFrameManager.swift +175 -0
- package/ios/BarcodeFrameOverlayView.swift +102 -0
- package/ios/CameraManager.swift +396 -0
- package/ios/CoordinateTransformer.swift +140 -0
- package/ios/FocusAreaOverlayView.swift +161 -0
- package/ios/Models.swift +341 -0
- package/ios/Protocols.swift +194 -0
- package/ios/ScannerView.h +14 -0
- package/ios/ScannerView.mm +358 -0
- package/ios/ScannerViewImpl.swift +580 -0
- package/ios/react-native-scanner-Bridging-Header.h +26 -0
- package/lib/module/CameraInfoModule.js +8 -0
- package/lib/module/CameraInfoModule.js.map +1 -0
- package/lib/module/ScannerViewNativeComponent.ts +121 -0
- package/lib/module/hooks/useCameraInfo.js +106 -0
- package/lib/module/hooks/useCameraInfo.js.map +1 -0
- package/lib/module/index.js +13 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +47 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/CameraInfoModule.d.ts +8 -0
- package/lib/typescript/src/CameraInfoModule.d.ts.map +1 -0
- package/lib/typescript/src/ScannerViewNativeComponent.d.ts +91 -0
- package/lib/typescript/src/ScannerViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useCameraInfo.d.ts +25 -0
- package/lib/typescript/src/hooks/useCameraInfo.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +8 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +145 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +178 -0
- package/src/CameraInfoModule.ts +11 -0
- package/src/ScannerViewNativeComponent.ts +121 -0
- package/src/hooks/useCameraInfo.ts +190 -0
- package/src/index.tsx +30 -0
- package/src/types.ts +177 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
#import "ScannerView.h"
|
|
2
|
+
|
|
3
|
+
#import <react/renderer/components/ScannerViewSpec/ComponentDescriptors.h>
|
|
4
|
+
#import <react/renderer/components/ScannerViewSpec/EventEmitters.h>
|
|
5
|
+
#import <react/renderer/components/ScannerViewSpec/Props.h>
|
|
6
|
+
#import <react/renderer/components/ScannerViewSpec/RCTComponentViewHelpers.h>
|
|
7
|
+
|
|
8
|
+
#import "RCTFabricComponentsPlugins.h"
|
|
9
|
+
|
|
10
|
+
// Import of the generated Swift header is not required because we use dynamic lookup (NSClassFromString).
|
|
11
|
+
// If you later want to statically reference Swift symbols, import "<ProductModuleName>-Swift.h" instead,
|
|
12
|
+
// where ProductModuleName matches your target's Packaging > Product Module Name.
|
|
13
|
+
|
|
14
|
+
using namespace facebook::react;
|
|
15
|
+
|
|
16
|
+
// No need to forward-declare ScannerViewImpl now, since we will use dynamic lookup at runtime.
|
|
17
|
+
|
|
18
|
+
@interface ScannerView () <RCTScannerViewViewProtocol>
|
|
19
|
+
@property (nonatomic, strong) UIView *scannerImpl;
|
|
20
|
+
@end
|
|
21
|
+
|
|
22
|
+
@implementation ScannerView
|
|
23
|
+
|
|
24
|
+
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
|
25
|
+
{
|
|
26
|
+
return concreteComponentDescriptorProvider<ScannerViewComponentDescriptor>();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
- (instancetype)initWithFrame:(CGRect)frame
|
|
30
|
+
{
|
|
31
|
+
if (self = [super initWithFrame:frame]) {
|
|
32
|
+
static const auto defaultProps = std::make_shared<const ScannerViewProps>();
|
|
33
|
+
_props = defaultProps;
|
|
34
|
+
|
|
35
|
+
NSLog(@"[ScannerView] 🚀 Starting initialization...");
|
|
36
|
+
|
|
37
|
+
// Initialize Swift implementation
|
|
38
|
+
// Try with module name first (Scanner is the module name from Scanner.podspec)
|
|
39
|
+
Class scannerImplClass = NSClassFromString(@"ScannerViewImpl");
|
|
40
|
+
if (!scannerImplClass) {
|
|
41
|
+
scannerImplClass = NSClassFromString(@"Scanner.ScannerViewImpl");
|
|
42
|
+
}
|
|
43
|
+
if (!scannerImplClass) {
|
|
44
|
+
scannerImplClass = NSClassFromString(@"react_native_scanner.ScannerViewImpl");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (scannerImplClass) {
|
|
48
|
+
NSLog(@"[ScannerView] ✅ Found ScannerViewImpl class: %@", scannerImplClass);
|
|
49
|
+
|
|
50
|
+
// Create instance
|
|
51
|
+
_scannerImpl = [[scannerImplClass alloc] initWithFrame:CGRectZero];
|
|
52
|
+
|
|
53
|
+
if (_scannerImpl) {
|
|
54
|
+
NSLog(@"[ScannerView] ✅ ScannerViewImpl instance created successfully");
|
|
55
|
+
|
|
56
|
+
// Try to set delegate using the property directly
|
|
57
|
+
if ([_scannerImpl respondsToSelector:@selector(setDelegate:)]) {
|
|
58
|
+
[_scannerImpl performSelector:@selector(setDelegate:) withObject:self];
|
|
59
|
+
NSLog(@"[ScannerView] ✅ Delegate set successfully using setDelegate:");
|
|
60
|
+
} else {
|
|
61
|
+
NSLog(@"[ScannerView] ⚠️ setDelegate: selector not found");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// IMPORTANT (Fabric): set the component's contentView to our Swift implementation.
|
|
65
|
+
// Fabric will size `contentView` via `updateLayoutMetrics`, not necessarily via `layoutSubviews`.
|
|
66
|
+
self.contentView = _scannerImpl;
|
|
67
|
+
_scannerImpl.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
|
68
|
+
_scannerImpl.frame = self.bounds;
|
|
69
|
+
|
|
70
|
+
NSLog(@"[ScannerView] ✅ View hierarchy setup complete (contentView bounds: %@, scannerImpl frame: %@)",
|
|
71
|
+
NSStringFromCGRect(self.contentView.bounds),
|
|
72
|
+
NSStringFromCGRect(_scannerImpl.frame));
|
|
73
|
+
} else {
|
|
74
|
+
NSLog(@"[ScannerView] ❌ Failed to create ScannerViewImpl instance");
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
NSLog(@"[ScannerView] ❌ ERROR: ScannerViewImpl class not found!");
|
|
78
|
+
NSLog(@"[ScannerView] Tried: ScannerViewImpl, Scanner.ScannerViewImpl, react_native_scanner.ScannerViewImpl");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return self;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
- (void)updateLayoutMetrics:(LayoutMetrics const &)layoutMetrics oldLayoutMetrics:(LayoutMetrics const &)oldLayoutMetrics
|
|
86
|
+
{
|
|
87
|
+
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
|
|
88
|
+
|
|
89
|
+
// Fabric layout updates flow through here. Ensure the Swift view always matches our bounds.
|
|
90
|
+
if (_scannerImpl) {
|
|
91
|
+
_scannerImpl.frame = self.bounds;
|
|
92
|
+
NSLog(@"[ScannerView] 📏 updateLayoutMetrics - bounds: %@, scannerImpl frame: %@",
|
|
93
|
+
NSStringFromCGRect(self.bounds),
|
|
94
|
+
NSStringFromCGRect(_scannerImpl.frame));
|
|
95
|
+
} else {
|
|
96
|
+
NSLog(@"[ScannerView] 📏 updateLayoutMetrics - bounds: %@ (no scannerImpl yet)", NSStringFromCGRect(self.bounds));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
- (void)prepareForRecycle
|
|
101
|
+
{
|
|
102
|
+
[super prepareForRecycle];
|
|
103
|
+
NSLog(@"[ScannerView] prepareForRecycle called");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
|
|
107
|
+
{
|
|
108
|
+
[super mountChildComponentView:childComponentView index:index];
|
|
109
|
+
NSLog(@"[ScannerView] mountChildComponentView called at index: %ld", (long)index);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask
|
|
113
|
+
{
|
|
114
|
+
[super finalizeUpdates:updateMask];
|
|
115
|
+
NSLog(@"[ScannerView] 🔄 finalizeUpdates - frame: %@, bounds: %@", NSStringFromCGRect(self.frame), NSStringFromCGRect(self.bounds));
|
|
116
|
+
|
|
117
|
+
// Force layout when we have a valid frame
|
|
118
|
+
if (self.bounds.size.width > 0 && self.bounds.size.height > 0) {
|
|
119
|
+
if (_scannerImpl) {
|
|
120
|
+
_scannerImpl.frame = self.contentView.bounds;
|
|
121
|
+
NSLog(@"[ScannerView] 🔧 Force updated scannerImpl frame in finalizeUpdates: %@", NSStringFromCGRect(_scannerImpl.frame));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
- (void)layoutSubviews
|
|
127
|
+
{
|
|
128
|
+
[super layoutSubviews];
|
|
129
|
+
|
|
130
|
+
NSLog(@"[ScannerView] 📐 layoutSubviews - contentView bounds: %@", NSStringFromCGRect(self.contentView.bounds));
|
|
131
|
+
|
|
132
|
+
// Update the scanner impl frame to match contentView bounds
|
|
133
|
+
if (_scannerImpl) {
|
|
134
|
+
_scannerImpl.frame = self.contentView.bounds;
|
|
135
|
+
NSLog(@"[ScannerView] Updated scannerImpl frame to: %@", NSStringFromCGRect(_scannerImpl.frame));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
|
|
140
|
+
{
|
|
141
|
+
const auto &oldViewProps = *std::static_pointer_cast<ScannerViewProps const>(_props);
|
|
142
|
+
const auto &newViewProps = *std::static_pointer_cast<ScannerViewProps const>(props);
|
|
143
|
+
|
|
144
|
+
if (!_scannerImpl) {
|
|
145
|
+
[super updateProps:props oldProps:oldProps];
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Barcode types
|
|
150
|
+
if (oldViewProps.barcodeTypes != newViewProps.barcodeTypes) {
|
|
151
|
+
NSMutableArray *formats = [NSMutableArray new];
|
|
152
|
+
for (const auto &format : newViewProps.barcodeTypes) {
|
|
153
|
+
[formats addObject:[NSString stringWithUTF8String:format.c_str()]];
|
|
154
|
+
}
|
|
155
|
+
[_scannerImpl performSelector:@selector(setBarcodeTypes:) withObject:formats];
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Focus area (overlay + optional filtering)
|
|
159
|
+
auto focusAreaChanged = (
|
|
160
|
+
oldViewProps.focusArea.enabled != newViewProps.focusArea.enabled ||
|
|
161
|
+
oldViewProps.focusArea.showOverlay != newViewProps.focusArea.showOverlay ||
|
|
162
|
+
oldViewProps.focusArea.borderColor != newViewProps.focusArea.borderColor ||
|
|
163
|
+
oldViewProps.focusArea.tintColor != newViewProps.focusArea.tintColor ||
|
|
164
|
+
oldViewProps.focusArea.size.width != newViewProps.focusArea.size.width ||
|
|
165
|
+
oldViewProps.focusArea.size.height != newViewProps.focusArea.size.height ||
|
|
166
|
+
oldViewProps.focusArea.position.x != newViewProps.focusArea.position.x ||
|
|
167
|
+
oldViewProps.focusArea.position.y != newViewProps.focusArea.position.y
|
|
168
|
+
);
|
|
169
|
+
if (focusAreaChanged) {
|
|
170
|
+
NSMutableDictionary *focusAreaDict = [NSMutableDictionary dictionary];
|
|
171
|
+
|
|
172
|
+
[focusAreaDict setObject:@(newViewProps.focusArea.enabled) forKey:@"enabled"];
|
|
173
|
+
[focusAreaDict setObject:@(newViewProps.focusArea.showOverlay) forKey:@"showOverlay"];
|
|
174
|
+
|
|
175
|
+
if (!newViewProps.focusArea.borderColor.empty()) {
|
|
176
|
+
[focusAreaDict setObject:[NSString stringWithUTF8String:newViewProps.focusArea.borderColor.c_str()] forKey:@"borderColor"];
|
|
177
|
+
}
|
|
178
|
+
if (!newViewProps.focusArea.tintColor.empty()) {
|
|
179
|
+
[focusAreaDict setObject:[NSString stringWithUTF8String:newViewProps.focusArea.tintColor.c_str()] forKey:@"tintColor"];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// size: either number or {width,height}
|
|
183
|
+
if (newViewProps.focusArea.size.width > 0 || newViewProps.focusArea.size.height > 0) {
|
|
184
|
+
if (newViewProps.focusArea.size.width == newViewProps.focusArea.size.height) {
|
|
185
|
+
[focusAreaDict setObject:@(newViewProps.focusArea.size.width) forKey:@"size"];
|
|
186
|
+
} else {
|
|
187
|
+
[focusAreaDict setObject:@{
|
|
188
|
+
@"width": @(newViewProps.focusArea.size.width),
|
|
189
|
+
@"height": @(newViewProps.focusArea.size.height)
|
|
190
|
+
} forKey:@"size"];
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// position: {x,y} in 0-100
|
|
195
|
+
// Android defaults to 50/50 when position isn't provided.
|
|
196
|
+
// Codegen initializes missing nested fields to 0.0, so we only forward position when non-zero.
|
|
197
|
+
// Note: this means explicitly setting {x:0,y:0} from JS is not representable with this heuristic.
|
|
198
|
+
if (newViewProps.focusArea.position.x != 0.0 || newViewProps.focusArea.position.y != 0.0) {
|
|
199
|
+
[focusAreaDict setObject:@{
|
|
200
|
+
@"x": @(newViewProps.focusArea.position.x),
|
|
201
|
+
@"y": @(newViewProps.focusArea.position.y)
|
|
202
|
+
} forKey:@"position"];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if ([_scannerImpl respondsToSelector:@selector(configureFocusArea:)]) {
|
|
206
|
+
[_scannerImpl performSelector:@selector(configureFocusArea:) withObject:focusAreaDict];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Barcode frames overlay
|
|
211
|
+
auto barcodeFramesChanged = (
|
|
212
|
+
oldViewProps.barcodeFrames.enabled != newViewProps.barcodeFrames.enabled ||
|
|
213
|
+
oldViewProps.barcodeFrames.onlyInFocusArea != newViewProps.barcodeFrames.onlyInFocusArea ||
|
|
214
|
+
oldViewProps.barcodeFrames.color != newViewProps.barcodeFrames.color
|
|
215
|
+
);
|
|
216
|
+
if (barcodeFramesChanged) {
|
|
217
|
+
NSMutableDictionary *barcodeFramesDict = [NSMutableDictionary dictionary];
|
|
218
|
+
[barcodeFramesDict setObject:@(newViewProps.barcodeFrames.enabled) forKey:@"enabled"];
|
|
219
|
+
[barcodeFramesDict setObject:@(newViewProps.barcodeFrames.onlyInFocusArea) forKey:@"onlyInFocusArea"];
|
|
220
|
+
|
|
221
|
+
if (!newViewProps.barcodeFrames.color.empty()) {
|
|
222
|
+
[barcodeFramesDict setObject:[NSString stringWithUTF8String:newViewProps.barcodeFrames.color.c_str()] forKey:@"color"];
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if ([_scannerImpl respondsToSelector:@selector(configureBarcodeFrames:)]) {
|
|
226
|
+
[_scannerImpl performSelector:@selector(configureBarcodeFrames:) withObject:barcodeFramesDict];
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Torch
|
|
231
|
+
if (oldViewProps.torch != newViewProps.torch) {
|
|
232
|
+
NSNumber *torchValue = @(newViewProps.torch);
|
|
233
|
+
[_scannerImpl performSelector:@selector(setTorchEnabled:) withObject:torchValue];
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Zoom
|
|
237
|
+
if (oldViewProps.zoom != newViewProps.zoom) {
|
|
238
|
+
NSNumber *zoomValue = @(newViewProps.zoom);
|
|
239
|
+
[_scannerImpl performSelector:@selector(setZoomLevel:) withObject:zoomValue];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Pause scanning
|
|
243
|
+
if (oldViewProps.pauseScanning != newViewProps.pauseScanning) {
|
|
244
|
+
NSNumber *pauseValue = @(newViewProps.pauseScanning);
|
|
245
|
+
[_scannerImpl performSelector:@selector(setPauseScanning:) withObject:pauseValue];
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Barcode scan strategy
|
|
249
|
+
if (oldViewProps.barcodeScanStrategy != newViewProps.barcodeScanStrategy) {
|
|
250
|
+
NSString *strategy = [NSString stringWithUTF8String:newViewProps.barcodeScanStrategy.c_str()];
|
|
251
|
+
if ([_scannerImpl respondsToSelector:@selector(setBarcodeScanStrategy:)]) {
|
|
252
|
+
[_scannerImpl performSelector:@selector(setBarcodeScanStrategy:) withObject:strategy];
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Keep screen on
|
|
257
|
+
if (oldViewProps.keepScreenOn != newViewProps.keepScreenOn) {
|
|
258
|
+
NSNumber *keepScreenOnValue = @(newViewProps.keepScreenOn);
|
|
259
|
+
if ([_scannerImpl respondsToSelector:@selector(setKeepScreenOn:)]) {
|
|
260
|
+
[_scannerImpl performSelector:@selector(setKeepScreenOn:) withObject:keepScreenOnValue];
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Barcode emission interval
|
|
265
|
+
if (oldViewProps.barcodeEmissionInterval != newViewProps.barcodeEmissionInterval) {
|
|
266
|
+
NSNumber *intervalValue = @(newViewProps.barcodeEmissionInterval);
|
|
267
|
+
if ([_scannerImpl respondsToSelector:@selector(setBarcodeEmissionInterval:)]) {
|
|
268
|
+
[_scannerImpl performSelector:@selector(setBarcodeEmissionInterval:) withObject:intervalValue];
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
[super updateProps:props oldProps:oldProps];
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// MARK: - ScannerViewDelegate (implemented via performSelector to avoid Swift header dependency)
|
|
276
|
+
|
|
277
|
+
- (void)scannerDidDetectBarcodes:(NSArray<NSDictionary *> *)barcodes
|
|
278
|
+
{
|
|
279
|
+
if (_eventEmitter) {
|
|
280
|
+
auto scannerEventEmitter = std::static_pointer_cast<const ScannerViewEventEmitter>(_eventEmitter);
|
|
281
|
+
|
|
282
|
+
std::vector<ScannerViewEventEmitter::OnBarcodeScannedBarcodes> barcodesVector;
|
|
283
|
+
barcodesVector.reserve(barcodes.count);
|
|
284
|
+
for (NSDictionary *barcode in barcodes) {
|
|
285
|
+
ScannerViewEventEmitter::OnBarcodeScannedBarcodes item{};
|
|
286
|
+
NSString *dataStr = barcode[@"data"];
|
|
287
|
+
NSString *formatStr = barcode[@"format"];
|
|
288
|
+
NSNumber *timestampNum = barcode[@"timestamp"];
|
|
289
|
+
|
|
290
|
+
item.data = dataStr ? std::string([dataStr UTF8String]) : std::string();
|
|
291
|
+
item.format = formatStr ? std::string([formatStr UTF8String]) : std::string();
|
|
292
|
+
item.timestamp = timestampNum ? [timestampNum doubleValue] : 0.0;
|
|
293
|
+
|
|
294
|
+
// boundingBox is required by codegen; fill with zeros if missing
|
|
295
|
+
ScannerViewEventEmitter::OnBarcodeScannedBarcodesBoundingBox bbox{};
|
|
296
|
+
NSDictionary *box = barcode[@"boundingBox"];
|
|
297
|
+
if (box) {
|
|
298
|
+
bbox.left = [box[@"left"] doubleValue];
|
|
299
|
+
bbox.top = [box[@"top"] doubleValue];
|
|
300
|
+
bbox.right = [box[@"right"] doubleValue];
|
|
301
|
+
bbox.bottom = [box[@"bottom"] doubleValue];
|
|
302
|
+
} else {
|
|
303
|
+
bbox.left = 0.0;
|
|
304
|
+
bbox.top = 0.0;
|
|
305
|
+
bbox.right = 0.0;
|
|
306
|
+
bbox.bottom = 0.0;
|
|
307
|
+
}
|
|
308
|
+
item.boundingBox = bbox;
|
|
309
|
+
|
|
310
|
+
// area is required by codegen; default to 0 if absent
|
|
311
|
+
NSNumber *areaNum = barcode[@"area"];
|
|
312
|
+
item.area = areaNum ? [areaNum doubleValue] : 0.0;
|
|
313
|
+
|
|
314
|
+
barcodesVector.push_back(std::move(item));
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
ScannerViewEventEmitter::OnBarcodeScanned event = {
|
|
318
|
+
.barcodes = std::move(barcodesVector)
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
scannerEventEmitter->onBarcodeScanned(event);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
- (void)scannerDidEncounterError:(NSDictionary<NSString *,id> *)error
|
|
326
|
+
{
|
|
327
|
+
if (_eventEmitter) {
|
|
328
|
+
auto scannerEventEmitter = std::static_pointer_cast<const ScannerViewEventEmitter>(_eventEmitter);
|
|
329
|
+
|
|
330
|
+
ScannerViewEventEmitter::OnScannerError event = {
|
|
331
|
+
.error = std::string([[error objectForKey:@"error"] UTF8String]),
|
|
332
|
+
.code = std::string([[error objectForKey:@"code"] UTF8String])
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
scannerEventEmitter->onScannerError(event);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
- (void)scannerDidLoad:(NSDictionary<NSString *,id> *)info
|
|
340
|
+
{
|
|
341
|
+
if (_eventEmitter) {
|
|
342
|
+
auto scannerEventEmitter = std::static_pointer_cast<const ScannerViewEventEmitter>(_eventEmitter);
|
|
343
|
+
|
|
344
|
+
ScannerViewEventEmitter::OnLoad event = {
|
|
345
|
+
.success = [[info objectForKey:@"success"] boolValue],
|
|
346
|
+
.error = info[@"error"] ? std::string([[info objectForKey:@"error"] UTF8String]) : ""
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
scannerEventEmitter->onLoad(event);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
Class<RCTComponentViewProtocol> ScannerViewCls(void)
|
|
354
|
+
{
|
|
355
|
+
return ScannerView.class;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
@end
|