dynamsoft-capture-vision-react-native 3.4.1300 → 3.4.3010
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 +4 -4
- package/README.md +62 -62
- package/android/README.md +14 -14
- package/android/build.gradle +167 -163
- package/android/gradle.properties +20 -20
- package/android/settings.gradle +5 -5
- package/android/src/main/AndroidManifest.xml +6 -6
- package/android/src/main/AndroidManifest_noPackage.xml +5 -5
- package/android/src/main/cpp/CMakeLists.txt +21 -21
- package/android/src/main/cpp/ImgHO.cpp +94 -94
- package/android/src/main/cpp/ImgHO.h +34 -34
- package/android/src/main/cpp/JsiCore.cpp +296 -296
- package/android/src/main/cpp/JsiCore.h +51 -51
- package/android/src/main/cpp/JsiCvr.cpp +332 -332
- package/android/src/main/cpp/JsiCvr.h +54 -54
- package/android/src/main/cpp/JsiDbr.cpp +283 -283
- package/android/src/main/cpp/JsiDbr.h +26 -26
- package/android/src/main/cpp/JsiDce.cpp +59 -59
- package/android/src/main/cpp/JsiDce.h +17 -17
- package/android/src/main/cpp/JsiDcp.cpp +51 -51
- package/android/src/main/cpp/JsiDcp.h +31 -31
- package/android/src/main/cpp/JsiDdn.cpp +50 -50
- package/android/src/main/cpp/JsiDdn.h +28 -28
- package/android/src/main/cpp/JsiDlr.cpp +60 -60
- package/android/src/main/cpp/JsiDlr.h +26 -26
- package/android/src/main/cpp/JsiUtility.cpp +604 -604
- package/android/src/main/cpp/JsiUtility.h +26 -26
- package/android/src/main/cpp/RawBuffer.cpp +23 -23
- package/android/src/main/cpp/RawBuffer.h +24 -24
- package/android/src/main/cpp/android_log.h +14 -14
- package/android/src/main/dysJniLibsFor86/debug/arm64-v8a/librn_dys.so +0 -0
- package/android/src/main/dysJniLibsFor86/debug/armeabi-v7a/librn_dys.so +0 -0
- package/android/src/main/dysJniLibsFor86/debug/x86/librn_dys.so +0 -0
- package/android/src/main/dysJniLibsFor86/debug/x86_64/librn_dys.so +0 -0
- package/android/src/main/dysJniLibsFor86/release/arm64-v8a/librn_dys.so +0 -0
- package/android/src/main/dysJniLibsFor86/release/armeabi-v7a/librn_dys.so +0 -0
- package/android/src/main/dysJniLibsFor86/release/x86/librn_dys.so +0 -0
- package/android/src/main/dysJniLibsFor86/release/x86_64/librn_dys.so +0 -0
- package/android/src/main/java/com/dynamsoft/reactnativelib/CVRModule.kt +137 -137
- package/android/src/main/java/com/dynamsoft/reactnativelib/CameraViewManager.kt +62 -62
- package/android/src/main/java/com/dynamsoft/reactnativelib/DCEModule.kt +125 -125
- package/android/src/main/java/com/dynamsoft/reactnativelib/DynamsoftBaseModule.kt +8 -8
- package/android/src/main/java/com/dynamsoft/reactnativelib/ISAModule.kt +73 -73
- package/android/src/main/java/com/dynamsoft/reactnativelib/ImageEditorViewManager.kt +14 -14
- package/android/src/main/java/com/dynamsoft/reactnativelib/ImageEditorViewModule.kt +35 -35
- package/android/src/main/java/com/dynamsoft/reactnativelib/ImageManagerModule.kt +15 -15
- package/android/src/main/java/com/dynamsoft/reactnativelib/LicenseModule.kt +29 -29
- package/android/src/main/java/com/dynamsoft/reactnativelib/MultiCrossFilterModule.kt +83 -83
- package/android/src/main/java/com/dynamsoft/reactnativelib/ReactNativeDcvPackage.kt +32 -32
- package/android/src/main/java/com/dynamsoft/reactnativelib/VersionsModule.kt +41 -41
- package/android/src/main/java/com/dynamsoft/reactnativelib/basicutils/Basic.kt +44 -44
- package/android/src/main/java/com/dynamsoft/reactnativelib/basicutils/ForCore.kt +50 -50
- package/android/src/main/java/com/dynamsoft/reactnativelib/basicutils/ForCvr.kt +129 -129
- package/android/src/main/java/com/dynamsoft/reactnativelib/basicutils/ForDBR.kt +157 -157
- package/android/src/main/java/com/dynamsoft/reactnativelib/basicutils/ForDCE.kt +110 -110
- package/android/src/main/java/com/dynamsoft/reactnativelib/basicutils/ForDCP.kt +49 -49
- package/android/src/main/java/com/dynamsoft/reactnativelib/basicutils/ForDDN.kt +85 -85
- package/android/src/main/java/com/dynamsoft/reactnativelib/basicutils/ForDLR.kt +72 -72
- package/android/src/main/java/com/dynamsoft/reactnativelib/basicutils/ImageUtil.kt +58 -58
- package/android/src/main/java/com/dynamsoft/reactnativelib/core/ImageSourceAdapterModuleImpl.kt +120 -120
- package/android/src/main/java/com/dynamsoft/reactnativelib/cvr/CaptureVisionRouterModuleImpl.kt +306 -306
- package/android/src/main/java/com/dynamsoft/reactnativelib/dce/CameraEnhancerModuleImpl.kt +247 -247
- package/android/src/main/java/com/dynamsoft/reactnativelib/dce/CameraLifeCycleOwner.java +14 -14
- package/android/src/main/java/com/dynamsoft/reactnativelib/dce/CameraViewManagerImpl.kt +77 -77
- package/android/src/main/java/com/dynamsoft/reactnativelib/dce/ImageEditorViewManagerImpl.kt +15 -15
- package/android/src/main/java/com/dynamsoft/reactnativelib/dce/ImageEditorViewModuleImpl.kt +110 -110
- package/android/src/main/java/com/dynamsoft/reactnativelib/dce/RNCameraView.kt +20 -20
- package/android/src/main/java/com/dynamsoft/reactnativelib/dce/RNImageEditorView.kt +19 -19
- package/android/src/main/java/com/dynamsoft/reactnativelib/license/LicenseModuleImpl.kt +39 -39
- package/android/src/main/java/com/dynamsoft/reactnativelib/utility/ImageManagerModuleImpl.kt +120 -120
- package/android/src/main/java/com/dynamsoft/reactnativelib/utility/MultiCrossFilterModuleImpl.kt +111 -111
- package/app.plugin.js +21 -21
- package/dynamsoft-capture-vision-react-native.podspec +24 -24
- package/ios/CPP/DSImageData+HostObject.h +18 -18
- package/ios/CPP/DSImageData+HostObject.mm +38 -38
- package/ios/CPP/ImageDataHostObject.cpp +87 -87
- package/ios/CPP/ImageDataHostObject.hpp +35 -35
- package/ios/CPP/MutableRawBuffer.cpp +23 -23
- package/ios/CPP/MutableRawBuffer.hpp +23 -23
- package/ios/CPP/RNDynamsoft+JSI.h +22 -22
- package/ios/CPP/RNDynamsoft+JSI.mm +303 -303
- package/ios/CPP/RNDynamsoft+Json.h +93 -93
- package/ios/CPP/RNDynamsoft+Json.m +733 -733
- package/ios/CPP/YeetJSIUtils.h +56 -56
- package/ios/CPP/YeetJSIUtils.mm +208 -208
- package/ios/RNDynamsoftCameraView.h +31 -31
- package/ios/RNDynamsoftCameraView.m +108 -108
- package/ios/RNDynamsoftCameraViewManager.h +14 -14
- package/ios/RNDynamsoftCameraViewManager.m +195 -195
- package/ios/RNDynamsoftCaptureVisionRouter.h +18 -18
- package/ios/RNDynamsoftCaptureVisionRouter.mm +532 -532
- package/ios/RNDynamsoftImageEditorView.h +17 -17
- package/ios/RNDynamsoftImageEditorView.m +25 -25
- package/ios/RNDynamsoftImageEditorViewManager.h +14 -14
- package/ios/RNDynamsoftImageEditorViewManager.mm +183 -183
- package/ios/RNDynamsoftImageManager.h +14 -14
- package/ios/RNDynamsoftImageManager.mm +369 -369
- package/ios/RNDynamsoftImageSourceAdapter.h +19 -19
- package/ios/RNDynamsoftImageSourceAdapter.mm +255 -255
- package/ios/RNDynamsoftLicense.h +14 -14
- package/ios/RNDynamsoftLicense.m +62 -62
- package/ios/RNDynamsoftMultiCrossFilter.h +14 -14
- package/ios/RNDynamsoftMultiCrossFilter.m +145 -145
- package/ios/RNDynamsoftVersions.h +13 -13
- package/ios/RNDynamsoftVersions.m +27 -27
- package/package.json +48 -48
- package/src/NativeDynamsoftVersionsModule.tsx +20 -20
- package/src/VersionsModule.tsx +7 -7
- package/src/core/CapturedResultBase.tsx +18 -18
- package/src/core/CapturedResultItem.tsx +23 -23
- package/src/core/CoreModule.tsx +9 -9
- package/src/core/DSRect.tsx +29 -29
- package/src/core/EnumCaptureResultItemType.tsx +52 -52
- package/src/core/EnumColourChannelUsageType.tsx +26 -26
- package/src/core/EnumCrossVerificationStatus.tsx +46 -46
- package/src/core/EnumGrayscaleEnhancementMode.tsx +46 -46
- package/src/core/EnumGrayscaleTransformationMode.tsx +35 -35
- package/src/core/EnumImageFileFormat.tsx +6 -6
- package/src/core/EnumPixelFormat.tsx +53 -53
- package/src/core/ImageData.tsx +87 -87
- package/src/core/ImageSourceAdapter.tsx +160 -160
- package/src/core/NativeDynamsoftImageSourceAdapterModule.tsx +29 -29
- package/src/core/Point.tsx +13 -13
- package/src/core/Quadrilateral.tsx +12 -12
- package/src/core/index.tsx +18 -18
- package/src/cvr/CaptureVisionRouter.tsx +683 -683
- package/src/cvr/CaptureVisionRouterModule.tsx +9 -9
- package/src/cvr/CapturedResult.tsx +123 -123
- package/src/cvr/CapturedResultFilter.tsx +13 -13
- package/src/cvr/CapturedResultReceiver.tsx +71 -71
- package/src/cvr/EnumPresetTemplate.tsx +81 -81
- package/src/cvr/NativeDynamsoftCaptureVisionRouterModule.tsx +25 -25
- package/src/cvr/SimplifiedCaptureVisionSettings.tsx +61 -61
- package/src/cvr/index.tsx +11 -11
- package/src/dbr/BarcodeDetails.tsx +51 -51
- package/src/dbr/BarcodeReaderModule.tsx +9 -9
- package/src/dbr/BarcodeResultItem.tsx +65 -65
- package/src/dbr/DecodedBarcodesResult.tsx +14 -14
- package/src/dbr/ECISegment.tsx +23 -23
- package/src/dbr/EnumBarcodeFormat.tsx +112 -112
- package/src/dbr/EnumDeblurMode.tsx +29 -29
- package/src/dbr/EnumLocalizationMode.tsx +27 -27
- package/src/dbr/EnumQRCodeErrorCorrectionLevel.tsx +6 -6
- package/src/dbr/SimplifiedBarcodeReaderSettings.tsx +80 -80
- package/src/dbr/index.tsx +9 -9
- package/src/dce/CameraEnhancer.tsx +254 -254
- package/src/dce/CameraEnhancerModule.tsx +9 -9
- package/src/dce/CameraView.tsx +100 -100
- package/src/dce/DynamsoftCameraViewNativeComponent.ts +96 -96
- package/src/dce/DynamsoftImageEditorViewNativeComponent.ts +9 -9
- package/src/dce/EnumCameraPosition.tsx +25 -25
- package/src/dce/EnumDrawingLayerId.tsx +17 -17
- package/src/dce/EnumEnhancedFeatures.tsx +24 -24
- package/src/dce/EnumFocusMode.tsx +6 -6
- package/src/dce/EnumResolution.tsx +8 -8
- package/src/dce/EnumTorchState.tsx +10 -10
- package/src/dce/FeedBack.tsx +28 -28
- package/src/dce/ImageEditorView.tsx +131 -131
- package/src/dce/NativeDynamsoftCameraViewModule.tsx +47 -47
- package/src/dce/NativeDynamsoftImageEditorViewModule.ts +9 -9
- package/src/dce/index.tsx +13 -13
- package/src/dcp/CodeParserDedicatorModule.tsx +9 -9
- package/src/dcp/CodeParserModule.tsx +9 -9
- package/src/dcp/EnumMappingStatus.tsx +14 -14
- package/src/dcp/EnumValidationStatus.tsx +14 -14
- package/src/dcp/ParsedResult.tsx +14 -14
- package/src/dcp/ParsedResultItem.tsx +50 -50
- package/src/dcp/index.tsx +8 -8
- package/src/ddn/DeskewedImageResultItem.tsx +40 -40
- package/src/ddn/DetectedQuadResultItem.tsx +31 -31
- package/src/ddn/DocumentNormalizerModule.tsx +9 -9
- package/src/ddn/EnhancedImageResultItem.tsx +20 -20
- package/src/ddn/EnumImageColourMode.tsx +14 -14
- package/src/ddn/ProcessedDocumentResult.tsx +27 -27
- package/src/ddn/SimplifiedDocumentNormalizerSettings.tsx +65 -65
- package/src/ddn/index.tsx +11 -11
- package/src/dip/ImageProcessingModule.tsx +9 -9
- package/src/dip/index.tsx +1 -1
- package/src/dlr/CharacterResult.tsx +28 -28
- package/src/dlr/LabelRecognizerModule.tsx +9 -9
- package/src/dlr/RecognizedTextLinesResult.tsx +19 -19
- package/src/dlr/SimplifiedLabelRecognizerSettings.tsx +33 -33
- package/src/dlr/TextLineResultItem.tsx +41 -41
- package/src/dlr/index.tsx +8 -8
- package/src/index.tsx +13 -13
- package/src/license/LicenseManager.tsx +49 -49
- package/src/license/LicenseModule.tsx +9 -9
- package/src/license/NativeDynamsoftLicenseModule.tsx +7 -7
- package/src/license/index.tsx +7 -7
- package/src/utility/CrossVerificationCriteria.tsx +11 -11
- package/src/utility/EnumFilterType.tsx +5 -5
- package/src/utility/ImageManager.tsx +348 -348
- package/src/utility/MultiFrameResultCrossFilter.tsx +183 -183
- package/src/utility/NativeDynamsoftImageManagerModule.tsx +7 -7
- package/src/utility/NativeDynamsoftMultiCrossFilterModule.tsx +18 -18
- package/src/utility/UtilityModule.tsx +9 -9
- package/src/utility/index.tsx +4 -4
- package/android/.gitignore +0 -4
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright © Dynamsoft Corporation. All rights reserved.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
#import <Foundation/Foundation.h>
|
|
6
|
-
#import <React/RCTBridgeModule.h>
|
|
7
|
-
#import <React/RCTEventEmitter.h>
|
|
8
|
-
|
|
9
|
-
NS_ASSUME_NONNULL_BEGIN
|
|
10
|
-
|
|
11
|
-
@class DSImageSourceAdapter;
|
|
12
|
-
|
|
13
|
-
@interface RNDynamsoftImageSourceAdapter : RCTEventEmitter <RCTBridgeModule>
|
|
14
|
-
|
|
15
|
-
@property (nonatomic, strong) NSMutableDictionary<NSString *, DSImageSourceAdapter *> *isaDictionary;
|
|
16
|
-
|
|
17
|
-
@end
|
|
18
|
-
|
|
19
|
-
NS_ASSUME_NONNULL_END
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © Dynamsoft Corporation. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
#import <Foundation/Foundation.h>
|
|
6
|
+
#import <React/RCTBridgeModule.h>
|
|
7
|
+
#import <React/RCTEventEmitter.h>
|
|
8
|
+
|
|
9
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
10
|
+
|
|
11
|
+
@class DSImageSourceAdapter;
|
|
12
|
+
|
|
13
|
+
@interface RNDynamsoftImageSourceAdapter : RCTEventEmitter <RCTBridgeModule>
|
|
14
|
+
|
|
15
|
+
@property (nonatomic, strong) NSMutableDictionary<NSString *, DSImageSourceAdapter *> *isaDictionary;
|
|
16
|
+
|
|
17
|
+
@end
|
|
18
|
+
|
|
19
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -1,255 +1,255 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright © Dynamsoft Corporation. All rights reserved.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
#import "RNDynamsoftImageSourceAdapter.h"
|
|
6
|
-
#import <React/RCTBridge+Private.h>
|
|
7
|
-
#import <React/RCTUtils.h>
|
|
8
|
-
#import <jsi/jsi.h>
|
|
9
|
-
#import <sys/utsname.h>
|
|
10
|
-
#import "YeetJSIUtils.h"
|
|
11
|
-
#import <DynamsoftCaptureVisionBundle/DynamsoftCaptureVisionBundle.h>
|
|
12
|
-
#import "DSImageData+HostObject.h"
|
|
13
|
-
|
|
14
|
-
using namespace facebook::jsi;
|
|
15
|
-
using namespace facebook;
|
|
16
|
-
using namespace std;
|
|
17
|
-
|
|
18
|
-
@interface RNDynamsoftImageSourceAdapter ()
|
|
19
|
-
|
|
20
|
-
@end
|
|
21
|
-
|
|
22
|
-
@implementation RNDynamsoftImageSourceAdapter
|
|
23
|
-
|
|
24
|
-
RCT_EXPORT_MODULE(DynamsoftImageSourceAdapterModule)
|
|
25
|
-
|
|
26
|
-
- (instancetype)init
|
|
27
|
-
{
|
|
28
|
-
self = [super init];
|
|
29
|
-
if (self) {
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
return self;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(createDefaultNativeISA) {
|
|
36
|
-
DSImageSourceAdapter *adapter = [[DSImageSourceAdapter alloc] init];
|
|
37
|
-
NSString *key = [NSNumber numberWithUnsignedInteger:adapter.hash].stringValue;
|
|
38
|
-
[self.isaDictionary setValue:adapter forKey:key];
|
|
39
|
-
return key;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
RCT_EXPORT_METHOD(destroy:(NSString *)key) {
|
|
43
|
-
[self.isaDictionary removeObjectForKey:key];
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
RCT_EXPORT_METHOD(clearBuffer:(NSString *)key) {
|
|
47
|
-
[[self.isaDictionary valueForKey:key] clearBuffer];
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
RCT_EXPORT_METHOD(getImageCount:(NSString *)key
|
|
51
|
-
resolver:(RCTPromiseResolveBlock)resolve
|
|
52
|
-
rejecter:(RCTPromiseRejectBlock)reject)
|
|
53
|
-
{
|
|
54
|
-
resolve(@([self.isaDictionary valueForKey:key].imageCount));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
RCT_EXPORT_METHOD(isBufferEmpty:(NSString *)key
|
|
58
|
-
resolver:(RCTPromiseResolveBlock)resolve
|
|
59
|
-
rejecter:(RCTPromiseRejectBlock)reject)
|
|
60
|
-
{
|
|
61
|
-
resolve(@([self.isaDictionary valueForKey:key].isBufferEmpty));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
RCT_EXPORT_METHOD(getColourChannelUsageType:(NSString *)key
|
|
65
|
-
resolver:(RCTPromiseResolveBlock)resolve
|
|
66
|
-
rejecter:(RCTPromiseRejectBlock)reject)
|
|
67
|
-
{
|
|
68
|
-
resolve(@([self.isaDictionary valueForKey:key].colourChannelUsageType));
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
RCT_EXPORT_METHOD(setColourChannelUsageType:(NSString *)key
|
|
72
|
-
type:(NSInteger)type
|
|
73
|
-
resolver:(RCTPromiseResolveBlock)resolve
|
|
74
|
-
rejecter:(RCTPromiseRejectBlock)reject)
|
|
75
|
-
{
|
|
76
|
-
[self.isaDictionary valueForKey:key].colourChannelUsageType = (DSColourChannelUsageType)type;
|
|
77
|
-
resolve(@(true));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
RCT_EXPORT_METHOD(getMaximumImageCount:(NSString *)key
|
|
81
|
-
resolver:(RCTPromiseResolveBlock)resolve
|
|
82
|
-
rejecter:(RCTPromiseRejectBlock)reject)
|
|
83
|
-
{
|
|
84
|
-
resolve(@([self.isaDictionary valueForKey:key].maxImageCount));
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
RCT_EXPORT_METHOD(setMaximumImageCount:(NSString *)key
|
|
88
|
-
count:(NSInteger)count
|
|
89
|
-
resolver:(RCTPromiseResolveBlock)resolve
|
|
90
|
-
rejecter:(RCTPromiseRejectBlock)reject)
|
|
91
|
-
{
|
|
92
|
-
[self.isaDictionary valueForKey:key].maxImageCount = count;
|
|
93
|
-
resolve(@(true));
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
RCT_EXPORT_METHOD(setNextImageToReturn:(NSString *)key
|
|
97
|
-
imageId:(NSInteger)imageId
|
|
98
|
-
resolver:(RCTPromiseResolveBlock)resolve
|
|
99
|
-
rejecter:(RCTPromiseRejectBlock)reject)
|
|
100
|
-
{
|
|
101
|
-
[[self.isaDictionary valueForKey:key] setNextImageToReturn:imageId keepInBuffer:true];
|
|
102
|
-
resolve(@(true));
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
RCT_EXPORT_METHOD(startFetching:(NSString *)key) {
|
|
106
|
-
[[self.isaDictionary valueForKey:key] startFetching];
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
RCT_EXPORT_METHOD(stopFetching:(NSString *)key) {
|
|
110
|
-
[[self.isaDictionary valueForKey:key] stopFetching];
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(hasImage:(NSString *)key imageId:(NSInteger)imageId) {
|
|
114
|
-
return @([[self.isaDictionary valueForKey:key] hasImage:imageId]);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
#pragma mark - Private
|
|
118
|
-
- (NSMutableDictionary<NSString *,DSImageSourceAdapter *> *)isaDictionary {
|
|
119
|
-
if (!_isaDictionary) {
|
|
120
|
-
_isaDictionary = [[NSMutableDictionary alloc] init];
|
|
121
|
-
}
|
|
122
|
-
return _isaDictionary;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
- (void)addImage:(DSImageData *)data toISA:(NSString *)key {
|
|
126
|
-
[[self.isaDictionary valueForKey:key] addImageToBuffer:data];
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
- (DSImageData *)imageDataFromISA:(NSString *)key {
|
|
130
|
-
return [[self.isaDictionary valueForKey:key] getImage];
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
#pragma mark - Global JSI
|
|
134
|
-
// --- RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install) ---
|
|
135
|
-
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install)
|
|
136
|
-
{
|
|
137
|
-
RCTBridge *bridge = self.bridge;
|
|
138
|
-
|
|
139
|
-
if ([bridge respondsToSelector:NSSelectorFromString(@"parentBridge")]) {
|
|
140
|
-
bridge = [bridge valueForKey:@"parentBridge"];
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
RCTCxxBridge *cxxBridge = (RCTCxxBridge *)bridge;
|
|
144
|
-
if (cxxBridge == nil || cxxBridge.runtime == nil) {
|
|
145
|
-
return @false;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
auto jsiRuntime = (jsi::Runtime*) cxxBridge.runtime;
|
|
149
|
-
if (jsiRuntime == nil) {
|
|
150
|
-
return @false;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
install(*(facebook::jsi::Runtime *)cxxBridge.runtime, self);
|
|
154
|
-
return @true;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// --- Helper Functions and Lambdas ---
|
|
158
|
-
static void installHostFunction(
|
|
159
|
-
jsi::Runtime &jsiRuntime,
|
|
160
|
-
const char* name,
|
|
161
|
-
unsigned int argCount,
|
|
162
|
-
HostFunctionType hostFunction) {
|
|
163
|
-
|
|
164
|
-
auto func = Function::createFromHostFunction(
|
|
165
|
-
jsiRuntime,
|
|
166
|
-
PropNameID::forAscii(jsiRuntime, name),
|
|
167
|
-
argCount,
|
|
168
|
-
std::move(hostFunction)
|
|
169
|
-
);
|
|
170
|
-
jsiRuntime.global().setProperty(jsiRuntime, name, std::move(func));
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// --- JSI Installation Logic ---
|
|
174
|
-
static void install(jsi::Runtime &jsiRuntime, RNDynamsoftImageSourceAdapter *rnAdapter) {
|
|
175
|
-
using namespace jsi;
|
|
176
|
-
|
|
177
|
-
// Helper Lambda: Extract ImageDataHostObject from JSI Value
|
|
178
|
-
auto getHostImageData = [&](Runtime &runtime, const Value &value) -> std::optional<ImageDataHostObject> {
|
|
179
|
-
// Optimization: isObject() check does not require runtime
|
|
180
|
-
if (!value.isObject()) return std::nullopt;
|
|
181
|
-
auto obj = value.getObject(runtime);
|
|
182
|
-
// isHostObject<> requires runtime
|
|
183
|
-
if (!obj.isHostObject<ImageDataHostObject>(runtime)) return std::nullopt;
|
|
184
|
-
return ImageDataHostObject::getHOFromObject(runtime, obj);
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
// Helper Lambda: Create JSI Host Object from DSImageData and return
|
|
188
|
-
auto createJsiHostObject = [&](Runtime &runtime, DSImageData *imageData) -> Value {
|
|
189
|
-
if (!imageData) return Value::null();
|
|
190
|
-
auto host = [imageData hostObject];
|
|
191
|
-
return Object::createFromHostObject(runtime, std::make_shared<ImageDataHostObject>(host));
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
// ---------------------- isaGetImageData ----------------------
|
|
195
|
-
// isaGetImageData(key)
|
|
196
|
-
installHostFunction(jsiRuntime, "isaGetImageData", 1,
|
|
197
|
-
[rnAdapter, createJsiHostObject](Runtime &runtime, const Value &, const Value *arguments, size_t count) -> Value {
|
|
198
|
-
// 🔍 Argument Validation: Check count and key type (isString() no runtime)
|
|
199
|
-
if (count != 1 || !arguments[0].isString()) return Value::null();
|
|
200
|
-
|
|
201
|
-
NSString *key = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
202
|
-
DSImageData *imageData = [rnAdapter imageDataFromISA:key];
|
|
203
|
-
|
|
204
|
-
return createJsiHostObject(runtime, imageData);
|
|
205
|
-
}
|
|
206
|
-
);
|
|
207
|
-
|
|
208
|
-
// ---------------------- isaAddImageToBuffer ----------------------
|
|
209
|
-
// isaAddImageToBuffer(key, imageData)
|
|
210
|
-
installHostFunction(jsiRuntime, "isaAddImageToBuffer", 2,
|
|
211
|
-
[rnAdapter, getHostImageData](Runtime &runtime, const Value &, const Value *arguments, size_t count) -> Value {
|
|
212
|
-
// 🔍 Argument Validation: Check count and key type (isString() no runtime)
|
|
213
|
-
if (count != 2 || !arguments[0].isString() || !arguments[1].isObject()) return Value(false);
|
|
214
|
-
|
|
215
|
-
auto hostOpt = getHostImageData(runtime, arguments[1]);
|
|
216
|
-
if (!hostOpt) return Value(false);
|
|
217
|
-
|
|
218
|
-
NSString *key = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
219
|
-
DSImageData *data = [DSImageData imageDataFromHostObject:*hostOpt];
|
|
220
|
-
|
|
221
|
-
[rnAdapter addImage:data toISA:key];
|
|
222
|
-
return Value(true);
|
|
223
|
-
}
|
|
224
|
-
);
|
|
225
|
-
|
|
226
|
-
// ---------------------- imageDataToBase64 ----------------------
|
|
227
|
-
// imageDataToBase64(imageData)
|
|
228
|
-
installHostFunction(jsiRuntime, "imageDataToBase64", 1,
|
|
229
|
-
[getHostImageData](Runtime &runtime, const Value &, const Value *arguments, size_t count) -> Value {
|
|
230
|
-
// 🔍 Argument Validation: Check count and image object type (isObject() no runtime)
|
|
231
|
-
if (count != 1 || !arguments[0].isObject()) return Value(false);
|
|
232
|
-
|
|
233
|
-
auto hostOpt = getHostImageData(runtime, arguments[0]);
|
|
234
|
-
if (!hostOpt) return Value(false);
|
|
235
|
-
|
|
236
|
-
DSImageData *imageData = [DSImageData imageDataFromHostObject:*hostOpt];
|
|
237
|
-
|
|
238
|
-
NSError *error;
|
|
239
|
-
// Native code to convert DSImageData to Base64 (using JPEG representation)
|
|
240
|
-
UIImage *image = [imageData toUIImage:&error];
|
|
241
|
-
if (!error && image) {
|
|
242
|
-
// Compression quality set to 1.0 (highest quality)
|
|
243
|
-
NSData *data = UIImageJPEGRepresentation(image, 1.0);
|
|
244
|
-
NSString *base64String = [data base64EncodedStringWithOptions:0];
|
|
245
|
-
|
|
246
|
-
// convertNSStringToJSIString is assumed to be defined elsewhere
|
|
247
|
-
return convertNSStringToJSIString(runtime, base64String);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
return Value(false);
|
|
251
|
-
}
|
|
252
|
-
);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
@end
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © Dynamsoft Corporation. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
#import "RNDynamsoftImageSourceAdapter.h"
|
|
6
|
+
#import <React/RCTBridge+Private.h>
|
|
7
|
+
#import <React/RCTUtils.h>
|
|
8
|
+
#import <jsi/jsi.h>
|
|
9
|
+
#import <sys/utsname.h>
|
|
10
|
+
#import "YeetJSIUtils.h"
|
|
11
|
+
#import <DynamsoftCaptureVisionBundle/DynamsoftCaptureVisionBundle.h>
|
|
12
|
+
#import "DSImageData+HostObject.h"
|
|
13
|
+
|
|
14
|
+
using namespace facebook::jsi;
|
|
15
|
+
using namespace facebook;
|
|
16
|
+
using namespace std;
|
|
17
|
+
|
|
18
|
+
@interface RNDynamsoftImageSourceAdapter ()
|
|
19
|
+
|
|
20
|
+
@end
|
|
21
|
+
|
|
22
|
+
@implementation RNDynamsoftImageSourceAdapter
|
|
23
|
+
|
|
24
|
+
RCT_EXPORT_MODULE(DynamsoftImageSourceAdapterModule)
|
|
25
|
+
|
|
26
|
+
- (instancetype)init
|
|
27
|
+
{
|
|
28
|
+
self = [super init];
|
|
29
|
+
if (self) {
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
return self;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(createDefaultNativeISA) {
|
|
36
|
+
DSImageSourceAdapter *adapter = [[DSImageSourceAdapter alloc] init];
|
|
37
|
+
NSString *key = [NSNumber numberWithUnsignedInteger:adapter.hash].stringValue;
|
|
38
|
+
[self.isaDictionary setValue:adapter forKey:key];
|
|
39
|
+
return key;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
RCT_EXPORT_METHOD(destroy:(NSString *)key) {
|
|
43
|
+
[self.isaDictionary removeObjectForKey:key];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
RCT_EXPORT_METHOD(clearBuffer:(NSString *)key) {
|
|
47
|
+
[[self.isaDictionary valueForKey:key] clearBuffer];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
RCT_EXPORT_METHOD(getImageCount:(NSString *)key
|
|
51
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
52
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
53
|
+
{
|
|
54
|
+
resolve(@([self.isaDictionary valueForKey:key].imageCount));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
RCT_EXPORT_METHOD(isBufferEmpty:(NSString *)key
|
|
58
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
59
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
60
|
+
{
|
|
61
|
+
resolve(@([self.isaDictionary valueForKey:key].isBufferEmpty));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
RCT_EXPORT_METHOD(getColourChannelUsageType:(NSString *)key
|
|
65
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
66
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
67
|
+
{
|
|
68
|
+
resolve(@([self.isaDictionary valueForKey:key].colourChannelUsageType));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
RCT_EXPORT_METHOD(setColourChannelUsageType:(NSString *)key
|
|
72
|
+
type:(NSInteger)type
|
|
73
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
74
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
75
|
+
{
|
|
76
|
+
[self.isaDictionary valueForKey:key].colourChannelUsageType = (DSColourChannelUsageType)type;
|
|
77
|
+
resolve(@(true));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
RCT_EXPORT_METHOD(getMaximumImageCount:(NSString *)key
|
|
81
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
82
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
83
|
+
{
|
|
84
|
+
resolve(@([self.isaDictionary valueForKey:key].maxImageCount));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
RCT_EXPORT_METHOD(setMaximumImageCount:(NSString *)key
|
|
88
|
+
count:(NSInteger)count
|
|
89
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
90
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
91
|
+
{
|
|
92
|
+
[self.isaDictionary valueForKey:key].maxImageCount = count;
|
|
93
|
+
resolve(@(true));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
RCT_EXPORT_METHOD(setNextImageToReturn:(NSString *)key
|
|
97
|
+
imageId:(NSInteger)imageId
|
|
98
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
99
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
100
|
+
{
|
|
101
|
+
[[self.isaDictionary valueForKey:key] setNextImageToReturn:imageId keepInBuffer:true];
|
|
102
|
+
resolve(@(true));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
RCT_EXPORT_METHOD(startFetching:(NSString *)key) {
|
|
106
|
+
[[self.isaDictionary valueForKey:key] startFetching];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
RCT_EXPORT_METHOD(stopFetching:(NSString *)key) {
|
|
110
|
+
[[self.isaDictionary valueForKey:key] stopFetching];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(hasImage:(NSString *)key imageId:(NSInteger)imageId) {
|
|
114
|
+
return @([[self.isaDictionary valueForKey:key] hasImage:imageId]);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
#pragma mark - Private
|
|
118
|
+
- (NSMutableDictionary<NSString *,DSImageSourceAdapter *> *)isaDictionary {
|
|
119
|
+
if (!_isaDictionary) {
|
|
120
|
+
_isaDictionary = [[NSMutableDictionary alloc] init];
|
|
121
|
+
}
|
|
122
|
+
return _isaDictionary;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
- (void)addImage:(DSImageData *)data toISA:(NSString *)key {
|
|
126
|
+
[[self.isaDictionary valueForKey:key] addImageToBuffer:data];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
- (DSImageData *)imageDataFromISA:(NSString *)key {
|
|
130
|
+
return [[self.isaDictionary valueForKey:key] getImage];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
#pragma mark - Global JSI
|
|
134
|
+
// --- RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install) ---
|
|
135
|
+
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install)
|
|
136
|
+
{
|
|
137
|
+
RCTBridge *bridge = self.bridge;
|
|
138
|
+
|
|
139
|
+
if ([bridge respondsToSelector:NSSelectorFromString(@"parentBridge")]) {
|
|
140
|
+
bridge = [bridge valueForKey:@"parentBridge"];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
RCTCxxBridge *cxxBridge = (RCTCxxBridge *)bridge;
|
|
144
|
+
if (cxxBridge == nil || cxxBridge.runtime == nil) {
|
|
145
|
+
return @false;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
auto jsiRuntime = (jsi::Runtime*) cxxBridge.runtime;
|
|
149
|
+
if (jsiRuntime == nil) {
|
|
150
|
+
return @false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
install(*(facebook::jsi::Runtime *)cxxBridge.runtime, self);
|
|
154
|
+
return @true;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// --- Helper Functions and Lambdas ---
|
|
158
|
+
static void installHostFunction(
|
|
159
|
+
jsi::Runtime &jsiRuntime,
|
|
160
|
+
const char* name,
|
|
161
|
+
unsigned int argCount,
|
|
162
|
+
HostFunctionType hostFunction) {
|
|
163
|
+
|
|
164
|
+
auto func = Function::createFromHostFunction(
|
|
165
|
+
jsiRuntime,
|
|
166
|
+
PropNameID::forAscii(jsiRuntime, name),
|
|
167
|
+
argCount,
|
|
168
|
+
std::move(hostFunction)
|
|
169
|
+
);
|
|
170
|
+
jsiRuntime.global().setProperty(jsiRuntime, name, std::move(func));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// --- JSI Installation Logic ---
|
|
174
|
+
static void install(jsi::Runtime &jsiRuntime, RNDynamsoftImageSourceAdapter *rnAdapter) {
|
|
175
|
+
using namespace jsi;
|
|
176
|
+
|
|
177
|
+
// Helper Lambda: Extract ImageDataHostObject from JSI Value
|
|
178
|
+
auto getHostImageData = [&](Runtime &runtime, const Value &value) -> std::optional<ImageDataHostObject> {
|
|
179
|
+
// Optimization: isObject() check does not require runtime
|
|
180
|
+
if (!value.isObject()) return std::nullopt;
|
|
181
|
+
auto obj = value.getObject(runtime);
|
|
182
|
+
// isHostObject<> requires runtime
|
|
183
|
+
if (!obj.isHostObject<ImageDataHostObject>(runtime)) return std::nullopt;
|
|
184
|
+
return ImageDataHostObject::getHOFromObject(runtime, obj);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
// Helper Lambda: Create JSI Host Object from DSImageData and return
|
|
188
|
+
auto createJsiHostObject = [&](Runtime &runtime, DSImageData *imageData) -> Value {
|
|
189
|
+
if (!imageData) return Value::null();
|
|
190
|
+
auto host = [imageData hostObject];
|
|
191
|
+
return Object::createFromHostObject(runtime, std::make_shared<ImageDataHostObject>(host));
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// ---------------------- isaGetImageData ----------------------
|
|
195
|
+
// isaGetImageData(key)
|
|
196
|
+
installHostFunction(jsiRuntime, "isaGetImageData", 1,
|
|
197
|
+
[rnAdapter, createJsiHostObject](Runtime &runtime, const Value &, const Value *arguments, size_t count) -> Value {
|
|
198
|
+
// 🔍 Argument Validation: Check count and key type (isString() no runtime)
|
|
199
|
+
if (count != 1 || !arguments[0].isString()) return Value::null();
|
|
200
|
+
|
|
201
|
+
NSString *key = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
202
|
+
DSImageData *imageData = [rnAdapter imageDataFromISA:key];
|
|
203
|
+
|
|
204
|
+
return createJsiHostObject(runtime, imageData);
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
// ---------------------- isaAddImageToBuffer ----------------------
|
|
209
|
+
// isaAddImageToBuffer(key, imageData)
|
|
210
|
+
installHostFunction(jsiRuntime, "isaAddImageToBuffer", 2,
|
|
211
|
+
[rnAdapter, getHostImageData](Runtime &runtime, const Value &, const Value *arguments, size_t count) -> Value {
|
|
212
|
+
// 🔍 Argument Validation: Check count and key type (isString() no runtime)
|
|
213
|
+
if (count != 2 || !arguments[0].isString() || !arguments[1].isObject()) return Value(false);
|
|
214
|
+
|
|
215
|
+
auto hostOpt = getHostImageData(runtime, arguments[1]);
|
|
216
|
+
if (!hostOpt) return Value(false);
|
|
217
|
+
|
|
218
|
+
NSString *key = convertJSIStringToNSString(runtime, arguments[0].getString(runtime));
|
|
219
|
+
DSImageData *data = [DSImageData imageDataFromHostObject:*hostOpt];
|
|
220
|
+
|
|
221
|
+
[rnAdapter addImage:data toISA:key];
|
|
222
|
+
return Value(true);
|
|
223
|
+
}
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
// ---------------------- imageDataToBase64 ----------------------
|
|
227
|
+
// imageDataToBase64(imageData)
|
|
228
|
+
installHostFunction(jsiRuntime, "imageDataToBase64", 1,
|
|
229
|
+
[getHostImageData](Runtime &runtime, const Value &, const Value *arguments, size_t count) -> Value {
|
|
230
|
+
// 🔍 Argument Validation: Check count and image object type (isObject() no runtime)
|
|
231
|
+
if (count != 1 || !arguments[0].isObject()) return Value(false);
|
|
232
|
+
|
|
233
|
+
auto hostOpt = getHostImageData(runtime, arguments[0]);
|
|
234
|
+
if (!hostOpt) return Value(false);
|
|
235
|
+
|
|
236
|
+
DSImageData *imageData = [DSImageData imageDataFromHostObject:*hostOpt];
|
|
237
|
+
|
|
238
|
+
NSError *error;
|
|
239
|
+
// Native code to convert DSImageData to Base64 (using JPEG representation)
|
|
240
|
+
UIImage *image = [imageData toUIImage:&error];
|
|
241
|
+
if (!error && image) {
|
|
242
|
+
// Compression quality set to 1.0 (highest quality)
|
|
243
|
+
NSData *data = UIImageJPEGRepresentation(image, 1.0);
|
|
244
|
+
NSString *base64String = [data base64EncodedStringWithOptions:0];
|
|
245
|
+
|
|
246
|
+
// convertNSStringToJSIString is assumed to be defined elsewhere
|
|
247
|
+
return convertNSStringToJSIString(runtime, base64String);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return Value(false);
|
|
251
|
+
}
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
@end
|
package/ios/RNDynamsoftLicense.h
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright © Dynamsoft Corporation. All rights reserved.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
#import <Foundation/Foundation.h>
|
|
6
|
-
#import <React/RCTBridgeModule.h>
|
|
7
|
-
|
|
8
|
-
NS_ASSUME_NONNULL_BEGIN
|
|
9
|
-
|
|
10
|
-
@interface RNDynamsoftLicense : NSObject <RCTBridgeModule>
|
|
11
|
-
|
|
12
|
-
@end
|
|
13
|
-
|
|
14
|
-
NS_ASSUME_NONNULL_END
|
|
1
|
+
/*
|
|
2
|
+
* Copyright © Dynamsoft Corporation. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
#import <Foundation/Foundation.h>
|
|
6
|
+
#import <React/RCTBridgeModule.h>
|
|
7
|
+
|
|
8
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
9
|
+
|
|
10
|
+
@interface RNDynamsoftLicense : NSObject <RCTBridgeModule>
|
|
11
|
+
|
|
12
|
+
@end
|
|
13
|
+
|
|
14
|
+
NS_ASSUME_NONNULL_END
|