react-native-earl-thermal-printer 1.0.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.
- package/README.md +441 -0
- package/android/build/.transforms/9bdecbc31aaf57a08a337d36d73153ec/results.bin +1 -0
- package/android/build/.transforms/9bdecbc31aaf57a08a337d36d73153ec/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/bc167481fd58833142c92ba32b0fc3e3/results.bin +1 -0
- package/android/build/.transforms/bc167481fd58833142c92ba32b0fc3e3/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/generated/source/buildConfig/debug/com/pinmi/react/printer/BuildConfig.java +10 -0
- package/android/build/generated/source/codegen/java/com/pinmi/react/printer/NativeBLEPrinterSpec.java +70 -0
- package/android/build/generated/source/codegen/java/com/pinmi/react/printer/NativeNetPrinterSpec.java +70 -0
- package/android/build/generated/source/codegen/java/com/pinmi/react/printer/NativeUSBPrinterSpec.java +62 -0
- package/android/build/generated/source/codegen/jni/CMakeLists.txt +46 -0
- package/android/build/generated/source/codegen/jni/RNThermalReceiptPrinterSpec-generated.cpp +190 -0
- package/android/build/generated/source/codegen/jni/RNThermalReceiptPrinterSpec.h +49 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNThermalReceiptPrinterSpec/ComponentDescriptors.h +22 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNThermalReceiptPrinterSpec/EventEmitters.cpp +18 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNThermalReceiptPrinterSpec/EventEmitters.h +19 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNThermalReceiptPrinterSpec/Props.cpp +21 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNThermalReceiptPrinterSpec/Props.h +20 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNThermalReceiptPrinterSpec/RNThermalReceiptPrinterSpecJSI-generated.cpp +205 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNThermalReceiptPrinterSpec/RNThermalReceiptPrinterSpecJSI.h +355 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNThermalReceiptPrinterSpec/ShadowNodes.cpp +19 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNThermalReceiptPrinterSpec/ShadowNodes.h +25 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNThermalReceiptPrinterSpec/States.cpp +18 -0
- package/android/build/generated/source/codegen/jni/react/renderer/components/RNThermalReceiptPrinterSpec/States.h +23 -0
- package/android/build/generated/source/codegen/schema.json +514 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml +13 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json +18 -0
- package/android/build/intermediates/aar_metadata/debug/aar-metadata.properties +5 -0
- package/android/build/intermediates/annotation_processor_list/debug/annotationProcessors.json +1 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/intermediates/compile_r_class_jar/debug/R.jar +0 -0
- package/android/build/intermediates/compile_symbol_list/debug/R.txt +1 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/merged.dir/values/values.xml +4 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
- package/android/build/intermediates/incremental/packageDebugAssets/merger.xml +2 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/BuildConfig.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/NativeBLEPrinterSpec.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/NativeNetPrinterSpec.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/NativeUSBPrinterSpec.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/RNBLEPrinterModule.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/RNNetPrinterModule.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/RNPrinterModule.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/RNPrinterPackage.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/RNUSBPrinterModule.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/BLEPrinterAdapter$1.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/BLEPrinterAdapter.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/BLEPrinterDevice.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/BLEPrinterDeviceId.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/NetPrinterAdapter$1.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/NetPrinterAdapter$2.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/NetPrinterAdapter.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/NetPrinterDevice.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/NetPrinterDeviceId.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/PrinterAdapter.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/PrinterDevice.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/PrinterDeviceId.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/USBPrinterAdapter$1.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/USBPrinterAdapter$2.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/USBPrinterAdapter.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/USBPrinterDevice.class +0 -0
- package/android/build/intermediates/javac/debug/classes/com/pinmi/react/printer/adapter/USBPrinterDeviceId.class +0 -0
- package/android/build/intermediates/local_only_symbol_list/debug/R-def.txt +3 -0
- package/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt +23 -0
- package/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml +13 -0
- package/android/build/intermediates/navigation_json/debug/navigation.json +1 -0
- package/android/build/intermediates/packaged_res/debug/values/values.xml +4 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt +2 -0
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +37 -0
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build.gradle +30 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +6 -0
- package/android/gradlew +160 -0
- package/android/gradlew.bat +90 -0
- package/android/src/androidTest/java/com/pinmi/react/printer/ExampleInstrumentedTest.java +26 -0
- package/android/src/main/AndroidManifest.xml +10 -0
- package/android/src/main/java/com/pinmi/react/printer/RNBLEPrinterModule.java +91 -0
- package/android/src/main/java/com/pinmi/react/printer/RNNetPrinterModule.java +95 -0
- package/android/src/main/java/com/pinmi/react/printer/RNPrinterModule.java +24 -0
- package/android/src/main/java/com/pinmi/react/printer/RNPrinterPackage.java +57 -0
- package/android/src/main/java/com/pinmi/react/printer/RNUSBPrinterModule.java +79 -0
- package/android/src/main/java/com/pinmi/react/printer/adapter/BLEPrinterAdapter.java +391 -0
- package/android/src/main/java/com/pinmi/react/printer/adapter/BLEPrinterDevice.java +33 -0
- package/android/src/main/java/com/pinmi/react/printer/adapter/BLEPrinterDeviceId.java +38 -0
- package/android/src/main/java/com/pinmi/react/printer/adapter/NetPrinterAdapter.java +433 -0
- package/android/src/main/java/com/pinmi/react/printer/adapter/NetPrinterDevice.java +30 -0
- package/android/src/main/java/com/pinmi/react/printer/adapter/NetPrinterDeviceId.java +48 -0
- package/android/src/main/java/com/pinmi/react/printer/adapter/PrinterAdapter.java +29 -0
- package/android/src/main/java/com/pinmi/react/printer/adapter/PrinterDevice.java +17 -0
- package/android/src/main/java/com/pinmi/react/printer/adapter/PrinterDeviceId.java +8 -0
- package/android/src/main/java/com/pinmi/react/printer/adapter/USBPrinterAdapter.java +468 -0
- package/android/src/main/java/com/pinmi/react/printer/adapter/USBPrinterDevice.java +41 -0
- package/android/src/main/java/com/pinmi/react/printer/adapter/USBPrinterDeviceId.java +49 -0
- package/android/src/main/res/values/strings.xml +3 -0
- package/android/src/test/java/com/pinmi/react/printer/ExampleUnitTest.java +17 -0
- package/dist/NativeBLEPrinter.d.ts +15 -0
- package/dist/NativeBLEPrinter.d.ts.map +1 -0
- package/dist/NativeBLEPrinter.js +3 -0
- package/dist/NativeBLEPrinter.js.map +1 -0
- package/dist/NativeNetPrinter.d.ts +15 -0
- package/dist/NativeNetPrinter.d.ts.map +1 -0
- package/dist/NativeNetPrinter.js +3 -0
- package/dist/NativeNetPrinter.js.map +1 -0
- package/dist/NativeUSBPrinter.d.ts +13 -0
- package/dist/NativeUSBPrinter.d.ts.map +1 -0
- package/dist/NativeUSBPrinter.js +3 -0
- package/dist/NativeUSBPrinter.js.map +1 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/EPToolkit.d.ts +9 -0
- package/dist/utils/EPToolkit.d.ts.map +1 -0
- package/dist/utils/EPToolkit.js +161 -0
- package/dist/utils/EPToolkit.js.map +1 -0
- package/dist/utils/buffer-helper.d.ts +12 -0
- package/dist/utils/buffer-helper.d.ts.map +1 -0
- package/dist/utils/buffer-helper.js +32 -0
- package/dist/utils/buffer-helper.js.map +1 -0
- package/ios/PrinterSDK/PrinterSDK.h +74 -0
- package/ios/PrinterSDK/libPrinterSDK.a +0 -0
- package/ios/RNBLEPrinter.h +24 -0
- package/ios/RNBLEPrinter.mm +251 -0
- package/ios/RNNetPrinter.h +25 -0
- package/ios/RNNetPrinter.mm +306 -0
- package/ios/RNThermalReceiptPrinter.xcodeproj/project.pbxproj +294 -0
- package/ios/RNThermalReceiptPrinter.xcworkspace/contents.xcworkspacedata +9 -0
- package/ios/RNUSBPrinter.h +19 -0
- package/ios/RNUSBPrinter.mm +80 -0
- package/package.json +70 -0
- package/react-native-earl-thermal-printer.podspec +22 -0
- package/src/NativeBLEPrinter.ts +16 -0
- package/src/NativeNetPrinter.ts +16 -0
- package/src/NativeUSBPrinter.ts +14 -0
- package/src/index.ts +160 -0
- package/src/utils/EPToolkit.ts +193 -0
- package/src/utils/buffer-helper.ts +42 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
//
|
|
2
|
+
// RNBLEPrinter.mm
|
|
3
|
+
// react-native-earl-thermal-printer
|
|
4
|
+
//
|
|
5
|
+
// BLE (Bluetooth) printer module for iOS using PrinterSDK.
|
|
6
|
+
// Migrated to Promise-based API for React Native New Architecture (TurboModules).
|
|
7
|
+
//
|
|
8
|
+
// Author: Ordovez, Earl Romeo
|
|
9
|
+
//
|
|
10
|
+
|
|
11
|
+
#import <Foundation/Foundation.h>
|
|
12
|
+
#import <UIKit/UIKit.h>
|
|
13
|
+
|
|
14
|
+
#import "RNBLEPrinter.h"
|
|
15
|
+
#import "PrinterSDK.h"
|
|
16
|
+
|
|
17
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
18
|
+
#import "RNThermalReceiptPrinterSpec.h"
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
@implementation RNBLEPrinter
|
|
22
|
+
|
|
23
|
+
- (dispatch_queue_t)methodQueue
|
|
24
|
+
{
|
|
25
|
+
return dispatch_get_main_queue();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
RCT_EXPORT_MODULE()
|
|
29
|
+
|
|
30
|
+
- (NSArray<NSString *> *)supportedEvents
|
|
31
|
+
{
|
|
32
|
+
return @[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
RCT_EXPORT_METHOD(init:(RCTPromiseResolveBlock)resolve
|
|
36
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
37
|
+
{
|
|
38
|
+
@try {
|
|
39
|
+
_printerArray = [NSMutableArray new];
|
|
40
|
+
m_printer = [[NSObject alloc] init];
|
|
41
|
+
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
42
|
+
selector:@selector(handleNetPrinterConnectedNotification:)
|
|
43
|
+
name:@"NetPrinterConnected"
|
|
44
|
+
object:nil];
|
|
45
|
+
[[PrinterSDK defaultPrinterSDK] scanPrintersWithCompletion:^(Printer* printer){}];
|
|
46
|
+
resolve(@"RNBLEPrinter initialized");
|
|
47
|
+
} @catch (NSException *exception) {
|
|
48
|
+
reject(@"ERR_BT_ADAPTER", exception.reason ?: @"No bluetooth adapter available", nil);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
- (void)handleNetPrinterConnectedNotification:(NSNotification *)notification
|
|
53
|
+
{
|
|
54
|
+
m_printer = nil;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
RCT_EXPORT_METHOD(getDeviceList:(RCTPromiseResolveBlock)resolve
|
|
58
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
59
|
+
{
|
|
60
|
+
@try {
|
|
61
|
+
if (!_printerArray) {
|
|
62
|
+
reject(@"ERR_NOT_INIT", @"Must call init function first", nil);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
[[PrinterSDK defaultPrinterSDK] scanPrintersWithCompletion:^(Printer* printer){
|
|
66
|
+
[self->_printerArray addObject:printer];
|
|
67
|
+
NSMutableArray *mapped = [NSMutableArray arrayWithCapacity:[self->_printerArray count]];
|
|
68
|
+
[self->_printerArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
|
69
|
+
NSDictionary *dict = @{
|
|
70
|
+
@"device_name" : printer.name ?: @"",
|
|
71
|
+
@"inner_mac_address" : printer.UUIDString ?: @""
|
|
72
|
+
};
|
|
73
|
+
[mapped addObject:dict];
|
|
74
|
+
}];
|
|
75
|
+
NSArray *uniqueArray = [[NSSet setWithArray:mapped] allObjects];
|
|
76
|
+
resolve(uniqueArray);
|
|
77
|
+
}];
|
|
78
|
+
} @catch (NSException *exception) {
|
|
79
|
+
reject(@"ERR_SCAN", exception.reason ?: @"Failed to scan devices", nil);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
RCT_EXPORT_METHOD(connectPrinter:(NSString *)innerAddress
|
|
84
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
85
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
86
|
+
{
|
|
87
|
+
@try {
|
|
88
|
+
__block BOOL found = NO;
|
|
89
|
+
__block Printer *selectedPrinter = nil;
|
|
90
|
+
[_printerArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
|
|
91
|
+
selectedPrinter = (Printer *)obj;
|
|
92
|
+
if ([innerAddress isEqualToString:(selectedPrinter.UUIDString)]) {
|
|
93
|
+
found = YES;
|
|
94
|
+
*stop = YES;
|
|
95
|
+
}
|
|
96
|
+
}];
|
|
97
|
+
|
|
98
|
+
if (found) {
|
|
99
|
+
[[PrinterSDK defaultPrinterSDK] connectBT:selectedPrinter];
|
|
100
|
+
[[NSNotificationCenter defaultCenter] postNotificationName:@"BLEPrinterConnected" object:nil];
|
|
101
|
+
m_printer = selectedPrinter;
|
|
102
|
+
NSDictionary *result = @{
|
|
103
|
+
@"device_name" : selectedPrinter.name ?: @"",
|
|
104
|
+
@"inner_mac_address" : selectedPrinter.UUIDString ?: @""
|
|
105
|
+
};
|
|
106
|
+
resolve(result);
|
|
107
|
+
} else {
|
|
108
|
+
reject(@"ERR_NOT_FOUND",
|
|
109
|
+
[NSString stringWithFormat:@"Can't find printer %@, please pair it in system settings first", innerAddress],
|
|
110
|
+
nil);
|
|
111
|
+
}
|
|
112
|
+
} @catch (NSException *exception) {
|
|
113
|
+
reject(@"ERR_CONNECT", exception.reason ?: @"Failed to connect", nil);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
RCT_EXPORT_METHOD(printRawData:(NSString *)base64Data
|
|
118
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
119
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
120
|
+
{
|
|
121
|
+
@try {
|
|
122
|
+
if (!m_printer) {
|
|
123
|
+
reject(@"ERR_NO_CONN", @"Not connected to a printer", nil);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
[[PrinterSDK defaultPrinterSDK] printText:base64Data];
|
|
127
|
+
resolve(nil);
|
|
128
|
+
} @catch (NSException *exception) {
|
|
129
|
+
reject(@"ERR_PRINT", exception.reason ?: @"Failed to print raw data", nil);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
RCT_EXPORT_METHOD(printImageData:(NSString *)imageUrl
|
|
134
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
135
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
136
|
+
{
|
|
137
|
+
@try {
|
|
138
|
+
if (!m_printer) {
|
|
139
|
+
reject(@"ERR_NO_CONN", @"Not connected to a printer", nil);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
NSURL *url = [NSURL URLWithString:imageUrl];
|
|
143
|
+
NSData *imageData = [NSData dataWithContentsOfURL:url];
|
|
144
|
+
if (imageData != nil) {
|
|
145
|
+
UIImage *image = [UIImage imageWithData:imageData];
|
|
146
|
+
UIImage *printImage = [self getPrintImage:image width:150 paddingX:250];
|
|
147
|
+
[[PrinterSDK defaultPrinterSDK] setPrintWidth:576];
|
|
148
|
+
[[PrinterSDK defaultPrinterSDK] printImage:printImage];
|
|
149
|
+
resolve(nil);
|
|
150
|
+
} else {
|
|
151
|
+
reject(@"ERR_IMAGE", @"Image not found", nil);
|
|
152
|
+
}
|
|
153
|
+
} @catch (NSException *exception) {
|
|
154
|
+
reject(@"ERR_PRINT_IMAGE", exception.reason ?: @"Failed to print image", nil);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
RCT_EXPORT_METHOD(printQrCode:(NSString *)qrCode
|
|
159
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
160
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
161
|
+
{
|
|
162
|
+
@try {
|
|
163
|
+
if (!m_printer) {
|
|
164
|
+
reject(@"ERR_NO_CONN", @"Not connected to a printer", nil);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (qrCode != nil) {
|
|
168
|
+
[[PrinterSDK defaultPrinterSDK] setPrintWidth:576];
|
|
169
|
+
[[PrinterSDK defaultPrinterSDK] printQrCode:qrCode];
|
|
170
|
+
resolve(nil);
|
|
171
|
+
} else {
|
|
172
|
+
reject(@"ERR_QR", @"QR code data is nil", nil);
|
|
173
|
+
}
|
|
174
|
+
} @catch (NSException *exception) {
|
|
175
|
+
reject(@"ERR_PRINT_QR", exception.reason ?: @"Failed to print QR code", nil);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
RCT_EXPORT_METHOD(closeConn)
|
|
180
|
+
{
|
|
181
|
+
@try {
|
|
182
|
+
if (m_printer) {
|
|
183
|
+
[[PrinterSDK defaultPrinterSDK] disconnect];
|
|
184
|
+
m_printer = nil;
|
|
185
|
+
}
|
|
186
|
+
} @catch (NSException *exception) {
|
|
187
|
+
NSLog(@"%@", exception.reason);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
RCT_EXPORT_METHOD(addListener:(NSString *)eventName)
|
|
192
|
+
{
|
|
193
|
+
// Required by RCTEventEmitter — no-op for BLE
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
RCT_EXPORT_METHOD(removeListeners:(double)count)
|
|
197
|
+
{
|
|
198
|
+
// Required by RCTEventEmitter — no-op for BLE
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
#pragma mark - Image Helpers
|
|
202
|
+
|
|
203
|
+
- (UIImage *)getPrintImage:(UIImage *)image width:(CGFloat)newWidth paddingX:(CGFloat)paddingX
|
|
204
|
+
{
|
|
205
|
+
CGFloat newHeight = (newWidth / image.size.width) * image.size.height;
|
|
206
|
+
CGSize newSize = CGSizeMake(newWidth, newHeight);
|
|
207
|
+
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0);
|
|
208
|
+
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
209
|
+
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
|
|
210
|
+
CGImageRef imageRef = image.CGImage;
|
|
211
|
+
CGContextDrawImage(context, CGRectMake(0, 0, newWidth, newHeight), imageRef);
|
|
212
|
+
CGImageRef newImageRef = CGBitmapContextCreateImage(context);
|
|
213
|
+
UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
|
|
214
|
+
CGImageRelease(newImageRef);
|
|
215
|
+
UIGraphicsEndImageContext();
|
|
216
|
+
|
|
217
|
+
UIImage *paddedImage = [self addImagePadding:newImage paddingX:paddingX paddingY:0];
|
|
218
|
+
return paddedImage;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
- (UIImage *)addImagePadding:(UIImage *)image paddingX:(CGFloat)paddingX paddingY:(CGFloat)paddingY
|
|
222
|
+
{
|
|
223
|
+
CGFloat width = image.size.width + paddingX;
|
|
224
|
+
CGFloat height = image.size.height + paddingY;
|
|
225
|
+
|
|
226
|
+
UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height), true, 0.0);
|
|
227
|
+
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
228
|
+
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
|
|
229
|
+
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
|
|
230
|
+
CGContextFillRect(context, CGRectMake(0, 0, width, height));
|
|
231
|
+
CGFloat originX = (width - image.size.width) / 2;
|
|
232
|
+
CGFloat originY = (height - image.size.height) / 2;
|
|
233
|
+
CGImageRef imageRef = image.CGImage;
|
|
234
|
+
CGContextDrawImage(context, CGRectMake(originX, originY, image.size.width, image.size.height), imageRef);
|
|
235
|
+
CGImageRef newImageRef = CGBitmapContextCreateImage(context);
|
|
236
|
+
UIImage *paddedImage = [UIImage imageWithCGImage:newImageRef];
|
|
237
|
+
CGImageRelease(newImageRef);
|
|
238
|
+
UIGraphicsEndImageContext();
|
|
239
|
+
|
|
240
|
+
return paddedImage;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
244
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
245
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
246
|
+
{
|
|
247
|
+
return std::make_shared<facebook::react::NativeBLEPrinterSpecJSI>(params);
|
|
248
|
+
}
|
|
249
|
+
#endif
|
|
250
|
+
|
|
251
|
+
@end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//
|
|
2
|
+
// RNNetPrinter.h
|
|
3
|
+
// react-native-earl-thermal-printer
|
|
4
|
+
//
|
|
5
|
+
// Author: Ordovez, Earl Romeo
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#import <React/RCTBridgeModule.h>
|
|
11
|
+
#import <React/RCTEventEmitter.h>
|
|
12
|
+
|
|
13
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
14
|
+
#import <RNThermalReceiptPrinterSpec/RNThermalReceiptPrinterSpec.h>
|
|
15
|
+
@interface RNNetPrinter : RCTEventEmitter <NativeNetPrinterSpec>
|
|
16
|
+
#else
|
|
17
|
+
@interface RNNetPrinter : RCTEventEmitter <RCTBridgeModule>
|
|
18
|
+
#endif
|
|
19
|
+
{
|
|
20
|
+
NSString *connected_ip;
|
|
21
|
+
NSString *current_scan_ip;
|
|
22
|
+
NSMutableArray *_printerArray;
|
|
23
|
+
bool is_scanning;
|
|
24
|
+
}
|
|
25
|
+
@end
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
//
|
|
2
|
+
// RNNetPrinter.mm
|
|
3
|
+
// react-native-earl-thermal-printer
|
|
4
|
+
//
|
|
5
|
+
// Network (TCP/IP) printer module for iOS using PrinterSDK.
|
|
6
|
+
// Migrated to Promise-based API for React Native New Architecture (TurboModules).
|
|
7
|
+
//
|
|
8
|
+
// Author: Ordovez, Earl Romeo
|
|
9
|
+
//
|
|
10
|
+
|
|
11
|
+
#import "RNNetPrinter.h"
|
|
12
|
+
#import "PrinterSDK.h"
|
|
13
|
+
#include <ifaddrs.h>
|
|
14
|
+
#include <arpa/inet.h>
|
|
15
|
+
#import <Foundation/Foundation.h>
|
|
16
|
+
#import <UIKit/UIKit.h>
|
|
17
|
+
|
|
18
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
19
|
+
#import "RNThermalReceiptPrinterSpec.h"
|
|
20
|
+
#endif
|
|
21
|
+
|
|
22
|
+
NSString *const EVENT_SCANNER_RESOLVED = @"scannerResolved";
|
|
23
|
+
NSString *const EVENT_SCANNER_RUNNING = @"scannerRunning";
|
|
24
|
+
|
|
25
|
+
#pragma mark - PrivateIP Helper
|
|
26
|
+
|
|
27
|
+
@interface PrivateIP : NSObject
|
|
28
|
+
- (NSString *)getIPAddress;
|
|
29
|
+
@end
|
|
30
|
+
|
|
31
|
+
@implementation PrivateIP
|
|
32
|
+
|
|
33
|
+
- (NSString *)getIPAddress
|
|
34
|
+
{
|
|
35
|
+
NSString *address = @"error";
|
|
36
|
+
struct ifaddrs *interfaces = NULL;
|
|
37
|
+
struct ifaddrs *temp_addr = NULL;
|
|
38
|
+
int success = getifaddrs(&interfaces);
|
|
39
|
+
if (success == 0) {
|
|
40
|
+
temp_addr = interfaces;
|
|
41
|
+
while (temp_addr != NULL) {
|
|
42
|
+
if (temp_addr->ifa_addr->sa_family == AF_INET) {
|
|
43
|
+
if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {
|
|
44
|
+
address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
temp_addr = temp_addr->ifa_next;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
freeifaddrs(interfaces);
|
|
51
|
+
return address;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@end
|
|
55
|
+
|
|
56
|
+
#pragma mark - RNNetPrinter
|
|
57
|
+
|
|
58
|
+
@implementation RNNetPrinter
|
|
59
|
+
|
|
60
|
+
- (dispatch_queue_t)methodQueue
|
|
61
|
+
{
|
|
62
|
+
return dispatch_get_main_queue();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
RCT_EXPORT_MODULE()
|
|
66
|
+
|
|
67
|
+
- (NSArray<NSString *> *)supportedEvents
|
|
68
|
+
{
|
|
69
|
+
return @[EVENT_SCANNER_RESOLVED, EVENT_SCANNER_RUNNING];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
RCT_EXPORT_METHOD(init:(RCTPromiseResolveBlock)resolve
|
|
73
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
74
|
+
{
|
|
75
|
+
connected_ip = nil;
|
|
76
|
+
is_scanning = NO;
|
|
77
|
+
_printerArray = [NSMutableArray new];
|
|
78
|
+
resolve(@"RNNetPrinter initialized");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
RCT_EXPORT_METHOD(getDeviceList:(RCTPromiseResolveBlock)resolve
|
|
82
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
83
|
+
{
|
|
84
|
+
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
85
|
+
selector:@selector(handlePrinterConnectedNotification:)
|
|
86
|
+
name:PrinterConnectedNotification
|
|
87
|
+
object:nil];
|
|
88
|
+
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
89
|
+
selector:@selector(handleBLEPrinterConnectedNotification:)
|
|
90
|
+
name:@"BLEPrinterConnected"
|
|
91
|
+
object:nil];
|
|
92
|
+
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
93
|
+
[self scan];
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Resolve immediately with empty array; discovered printers arrive via events
|
|
97
|
+
resolve(@[]);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
- (void)scan
|
|
101
|
+
{
|
|
102
|
+
@try {
|
|
103
|
+
PrivateIP *privateIP = [[PrivateIP alloc] init];
|
|
104
|
+
NSString *localIP = [privateIP getIPAddress];
|
|
105
|
+
is_scanning = YES;
|
|
106
|
+
[self sendEventWithName:EVENT_SCANNER_RUNNING body:@YES];
|
|
107
|
+
_printerArray = [NSMutableArray new];
|
|
108
|
+
|
|
109
|
+
NSString *prefix = [localIP substringToIndex:([localIP rangeOfString:@"." options:NSBackwardsSearch].location)];
|
|
110
|
+
NSInteger suffix = [[localIP substringFromIndex:([localIP rangeOfString:@"." options:NSBackwardsSearch].location)] intValue];
|
|
111
|
+
|
|
112
|
+
for (NSInteger i = 1; i < 255; i++) {
|
|
113
|
+
if (i == suffix) continue;
|
|
114
|
+
NSString *testIP = [NSString stringWithFormat:@"%@.%ld", prefix, (long)i];
|
|
115
|
+
current_scan_ip = testIP;
|
|
116
|
+
[[PrinterSDK defaultPrinterSDK] connectIP:testIP];
|
|
117
|
+
[NSThread sleepForTimeInterval:0.5];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:_printerArray];
|
|
121
|
+
NSArray *arrayWithoutDuplicates = [orderedSet array];
|
|
122
|
+
_printerArray = [arrayWithoutDuplicates mutableCopy];
|
|
123
|
+
|
|
124
|
+
[self sendEventWithName:EVENT_SCANNER_RESOLVED body:_printerArray];
|
|
125
|
+
} @catch (NSException *exception) {
|
|
126
|
+
NSLog(@"No connection");
|
|
127
|
+
}
|
|
128
|
+
[[PrinterSDK defaultPrinterSDK] disconnect];
|
|
129
|
+
is_scanning = NO;
|
|
130
|
+
[self sendEventWithName:EVENT_SCANNER_RUNNING body:@NO];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
- (void)handlePrinterConnectedNotification:(NSNotification *)notification
|
|
134
|
+
{
|
|
135
|
+
if (is_scanning) {
|
|
136
|
+
[_printerArray addObject:@{@"host": current_scan_ip, @"port": @9100}];
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
- (void)handleBLEPrinterConnectedNotification:(NSNotification *)notification
|
|
141
|
+
{
|
|
142
|
+
connected_ip = nil;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
RCT_EXPORT_METHOD(connectPrinter:(NSString *)host
|
|
146
|
+
port:(double)port
|
|
147
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
148
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
149
|
+
{
|
|
150
|
+
@try {
|
|
151
|
+
BOOL isConnectSuccess = [[PrinterSDK defaultPrinterSDK] connectIP:host];
|
|
152
|
+
if (!isConnectSuccess) {
|
|
153
|
+
reject(@"ERR_CONNECT",
|
|
154
|
+
[NSString stringWithFormat:@"Can't connect to printer %@:%d", host, (int)port],
|
|
155
|
+
nil);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
connected_ip = host;
|
|
160
|
+
[[NSNotificationCenter defaultCenter] postNotificationName:@"NetPrinterConnected" object:nil];
|
|
161
|
+
NSDictionary *result = @{
|
|
162
|
+
@"device_name" : [NSString stringWithFormat:@"%@:%d", host, (int)port],
|
|
163
|
+
@"host" : host,
|
|
164
|
+
@"port" : @((int)port)
|
|
165
|
+
};
|
|
166
|
+
resolve(result);
|
|
167
|
+
} @catch (NSException *exception) {
|
|
168
|
+
reject(@"ERR_CONNECT", exception.reason ?: @"Failed to connect", nil);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
RCT_EXPORT_METHOD(printRawData:(NSString *)base64Data
|
|
173
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
174
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
175
|
+
{
|
|
176
|
+
@try {
|
|
177
|
+
if (!connected_ip) {
|
|
178
|
+
reject(@"ERR_NO_CONN", @"Not connected to a printer", nil);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
[[PrinterSDK defaultPrinterSDK] printText:base64Data];
|
|
182
|
+
resolve(nil);
|
|
183
|
+
} @catch (NSException *exception) {
|
|
184
|
+
reject(@"ERR_PRINT", exception.reason ?: @"Failed to print raw data", nil);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
RCT_EXPORT_METHOD(printImageData:(NSString *)imageUrl
|
|
189
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
190
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
191
|
+
{
|
|
192
|
+
@try {
|
|
193
|
+
if (!connected_ip) {
|
|
194
|
+
reject(@"ERR_NO_CONN", @"Not connected to a printer", nil);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
NSURL *url = [NSURL URLWithString:imageUrl];
|
|
198
|
+
NSData *imageData = [NSData dataWithContentsOfURL:url];
|
|
199
|
+
if (imageData != nil) {
|
|
200
|
+
UIImage *image = [UIImage imageWithData:imageData];
|
|
201
|
+
UIImage *printImage = [self getPrintImage:image width:150 paddingX:250];
|
|
202
|
+
[[PrinterSDK defaultPrinterSDK] setPrintWidth:576];
|
|
203
|
+
[[PrinterSDK defaultPrinterSDK] printImage:printImage];
|
|
204
|
+
resolve(nil);
|
|
205
|
+
} else {
|
|
206
|
+
reject(@"ERR_IMAGE", @"Image not found", nil);
|
|
207
|
+
}
|
|
208
|
+
} @catch (NSException *exception) {
|
|
209
|
+
reject(@"ERR_PRINT_IMAGE", exception.reason ?: @"Failed to print image", nil);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
RCT_EXPORT_METHOD(printQrCode:(NSString *)qrCode
|
|
214
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
215
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
216
|
+
{
|
|
217
|
+
@try {
|
|
218
|
+
if (!connected_ip) {
|
|
219
|
+
reject(@"ERR_NO_CONN", @"Not connected to a printer", nil);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if (qrCode != nil) {
|
|
223
|
+
[[PrinterSDK defaultPrinterSDK] setPrintWidth:576];
|
|
224
|
+
[[PrinterSDK defaultPrinterSDK] printQrCode:qrCode];
|
|
225
|
+
resolve(nil);
|
|
226
|
+
} else {
|
|
227
|
+
reject(@"ERR_QR", @"QR code data is nil", nil);
|
|
228
|
+
}
|
|
229
|
+
} @catch (NSException *exception) {
|
|
230
|
+
reject(@"ERR_PRINT_QR", exception.reason ?: @"Failed to print QR code", nil);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
RCT_EXPORT_METHOD(closeConn)
|
|
235
|
+
{
|
|
236
|
+
@try {
|
|
237
|
+
if (connected_ip) {
|
|
238
|
+
[[PrinterSDK defaultPrinterSDK] disconnect];
|
|
239
|
+
connected_ip = nil;
|
|
240
|
+
}
|
|
241
|
+
} @catch (NSException *exception) {
|
|
242
|
+
NSLog(@"%@", exception.reason);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
RCT_EXPORT_METHOD(addListener:(NSString *)eventName)
|
|
247
|
+
{
|
|
248
|
+
// Required by RCTEventEmitter
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
RCT_EXPORT_METHOD(removeListeners:(double)count)
|
|
252
|
+
{
|
|
253
|
+
// Required by RCTEventEmitter
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
#pragma mark - Image Helpers
|
|
257
|
+
|
|
258
|
+
- (UIImage *)getPrintImage:(UIImage *)image width:(CGFloat)newWidth paddingX:(CGFloat)paddingX
|
|
259
|
+
{
|
|
260
|
+
CGFloat newHeight = (newWidth / image.size.width) * image.size.height;
|
|
261
|
+
CGSize newSize = CGSizeMake(newWidth, newHeight);
|
|
262
|
+
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0);
|
|
263
|
+
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
264
|
+
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
|
|
265
|
+
CGImageRef imageRef = image.CGImage;
|
|
266
|
+
CGContextDrawImage(context, CGRectMake(0, 0, newWidth, newHeight), imageRef);
|
|
267
|
+
CGImageRef newImageRef = CGBitmapContextCreateImage(context);
|
|
268
|
+
UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
|
|
269
|
+
CGImageRelease(newImageRef);
|
|
270
|
+
UIGraphicsEndImageContext();
|
|
271
|
+
|
|
272
|
+
UIImage *paddedImage = [self addImagePadding:newImage paddingX:paddingX paddingY:0];
|
|
273
|
+
return paddedImage;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
- (UIImage *)addImagePadding:(UIImage *)image paddingX:(CGFloat)paddingX paddingY:(CGFloat)paddingY
|
|
277
|
+
{
|
|
278
|
+
CGFloat width = image.size.width + paddingX;
|
|
279
|
+
CGFloat height = image.size.height + paddingY;
|
|
280
|
+
|
|
281
|
+
UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height), true, 0.0);
|
|
282
|
+
CGContextRef context = UIGraphicsGetCurrentContext();
|
|
283
|
+
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
|
|
284
|
+
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
|
|
285
|
+
CGContextFillRect(context, CGRectMake(0, 0, width, height));
|
|
286
|
+
CGFloat originX = (width - image.size.width) / 2;
|
|
287
|
+
CGFloat originY = (height - image.size.height) / 2;
|
|
288
|
+
CGImageRef imageRef = image.CGImage;
|
|
289
|
+
CGContextDrawImage(context, CGRectMake(originX, originY, image.size.width, image.size.height), imageRef);
|
|
290
|
+
CGImageRef newImageRef = CGBitmapContextCreateImage(context);
|
|
291
|
+
UIImage *paddedImage = [UIImage imageWithCGImage:newImageRef];
|
|
292
|
+
CGImageRelease(newImageRef);
|
|
293
|
+
UIGraphicsEndImageContext();
|
|
294
|
+
|
|
295
|
+
return paddedImage;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
299
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
300
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
301
|
+
{
|
|
302
|
+
return std::make_shared<facebook::react::NativeNetPrinterSpecJSI>(params);
|
|
303
|
+
}
|
|
304
|
+
#endif
|
|
305
|
+
|
|
306
|
+
@end
|