boot-nemonic-printer 0.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.
- package/.eslintrc.js +5 -0
- package/README.md +209 -0
- package/ai/example-ui-card-refactor.md +348 -0
- package/android/build.gradle +22 -0
- package/android/libs/NemonicSdk.aar +0 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/net/eventboot/nemonicprinter/BootNemonicPrinterModule.kt +509 -0
- package/build/BootNemonicPrinter.types.d.ts +44 -0
- package/build/BootNemonicPrinter.types.d.ts.map +1 -0
- package/build/BootNemonicPrinter.types.js +2 -0
- package/build/BootNemonicPrinter.types.js.map +1 -0
- package/build/BootNemonicPrinterModule.d.ts +36 -0
- package/build/BootNemonicPrinterModule.d.ts.map +1 -0
- package/build/BootNemonicPrinterModule.js +3 -0
- package/build/BootNemonicPrinterModule.js.map +1 -0
- package/build/constants/NBatteryStatus.d.ts +8 -0
- package/build/constants/NBatteryStatus.d.ts.map +1 -0
- package/build/constants/NBatteryStatus.js +7 -0
- package/build/constants/NBatteryStatus.js.map +1 -0
- package/build/constants/NCartridgeType.d.ts +35 -0
- package/build/constants/NCartridgeType.d.ts.map +1 -0
- package/build/constants/NCartridgeType.js +183 -0
- package/build/constants/NCartridgeType.js.map +1 -0
- package/build/constants/NConnectState.d.ts +8 -0
- package/build/constants/NConnectState.d.ts.map +1 -0
- package/build/constants/NConnectState.js +7 -0
- package/build/constants/NConnectState.js.map +1 -0
- package/build/constants/NPowerSaveMode.d.ts +6 -0
- package/build/constants/NPowerSaveMode.d.ts.map +1 -0
- package/build/constants/NPowerSaveMode.js +5 -0
- package/build/constants/NPowerSaveMode.js.map +1 -0
- package/build/constants/NPrintImageLength.d.ts +12 -0
- package/build/constants/NPrintImageLength.d.ts.map +1 -0
- package/build/constants/NPrintImageLength.js +12 -0
- package/build/constants/NPrintImageLength.js.map +1 -0
- package/build/constants/NPrintQuality.d.ts +7 -0
- package/build/constants/NPrintQuality.d.ts.map +1 -0
- package/build/constants/NPrintQuality.js +6 -0
- package/build/constants/NPrintQuality.js.map +1 -0
- package/build/constants/NPrinterStatus.d.ts +9 -0
- package/build/constants/NPrinterStatus.d.ts.map +1 -0
- package/build/constants/NPrinterStatus.js +8 -0
- package/build/constants/NPrinterStatus.js.map +1 -0
- package/build/constants/NPrinterType.d.ts +9 -0
- package/build/constants/NPrinterType.d.ts.map +1 -0
- package/build/constants/NPrinterType.js +8 -0
- package/build/constants/NPrinterType.js.map +1 -0
- package/build/constants/NResult.d.ts +51 -0
- package/build/constants/NResult.d.ts.map +1 -0
- package/build/constants/NResult.js +50 -0
- package/build/constants/NResult.js.map +1 -0
- package/build/index.d.ts +13 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +13 -0
- package/build/index.js.map +1 -0
- package/expo-module.config.json +9 -0
- package/ios/BootNemonicPrinter.podspec +31 -0
- package/ios/BootNemonicPrinterModule.swift +257 -0
- package/ios/Frameworks/NemonicSdk.framework/Headers/NemonicSdk-Swift.h +797 -0
- package/ios/Frameworks/NemonicSdk.framework/Headers/NemonicSdk.h +18 -0
- package/ios/Frameworks/NemonicSdk.framework/Info.plist +0 -0
- package/ios/Frameworks/NemonicSdk.framework/Modules/NemonicSdk.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo +0 -0
- package/ios/Frameworks/NemonicSdk.framework/Modules/NemonicSdk.swiftmodule/arm64-apple-ios.abi.json +12244 -0
- package/ios/Frameworks/NemonicSdk.framework/Modules/NemonicSdk.swiftmodule/arm64-apple-ios.private.swiftinterface +356 -0
- package/ios/Frameworks/NemonicSdk.framework/Modules/NemonicSdk.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/ios/Frameworks/NemonicSdk.framework/Modules/NemonicSdk.swiftmodule/arm64-apple-ios.swiftinterface +356 -0
- package/ios/Frameworks/NemonicSdk.framework/Modules/NemonicSdk.swiftmodule/arm64-apple-ios.swiftmodule +0 -0
- package/ios/Frameworks/NemonicSdk.framework/Modules/module.modulemap +11 -0
- package/ios/Frameworks/NemonicSdk.framework/NemonicSdk +0 -0
- package/ios/Frameworks/NemonicSdk.framework/_CodeSignature/CodeResources +237 -0
- package/package.json +44 -0
- package/src/BootNemonicPrinter.types.ts +50 -0
- package/src/BootNemonicPrinterModule.ts +48 -0
- package/src/constants/NBatteryStatus.ts +8 -0
- package/src/constants/NCartridgeType.ts +181 -0
- package/src/constants/NConnectState.ts +8 -0
- package/src/constants/NPowerSaveMode.ts +6 -0
- package/src/constants/NPrintImageLength.ts +11 -0
- package/src/constants/NPrintQuality.ts +7 -0
- package/src/constants/NPrinterStatus.ts +9 -0
- package/src/constants/NPrinterType.ts +9 -0
- package/src/constants/NResult.ts +51 -0
- package/src/index.ts +13 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import ExpoModulesCore
|
|
2
|
+
import NemonicSdk
|
|
3
|
+
import UIKit
|
|
4
|
+
|
|
5
|
+
private let MAX_IMAGE_SIZE = 196_603
|
|
6
|
+
private let EXCEED_MAX_SIZE = -900
|
|
7
|
+
private let PRINT_TAG = "NemonicPrintTimer"
|
|
8
|
+
|
|
9
|
+
public class BootNemonicPrinterModule: Module {
|
|
10
|
+
private var printerController: NPrinterController!
|
|
11
|
+
private var scanController: NPrinterScanController!
|
|
12
|
+
private var connectedPrinter: NPrinter?
|
|
13
|
+
fileprivate var printStartedAt: Date?
|
|
14
|
+
fileprivate var printSeq: Int = 0
|
|
15
|
+
|
|
16
|
+
public func definition() -> ModuleDefinition {
|
|
17
|
+
Name("BootNemonicPrinter")
|
|
18
|
+
|
|
19
|
+
Constant("MAX_IMAGE_SIZE") { MAX_IMAGE_SIZE }
|
|
20
|
+
Constant("SDK_VERSION") { "1.1.0" }
|
|
21
|
+
|
|
22
|
+
Events("onDeviceFound", "onDisconnected", "onPrintProgress", "onPrintComplete", "onNativeLog")
|
|
23
|
+
|
|
24
|
+
OnCreate {
|
|
25
|
+
let delegate = BootNemonicPrinterDelegate(owner: self)
|
|
26
|
+
self.delegateRef = delegate
|
|
27
|
+
self.printerController = NPrinterController(delegate)
|
|
28
|
+
self.scanController = NPrinterScanController(delegate)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// === BLE 스캔
|
|
32
|
+
AsyncFunction("startScan") { () -> Int in
|
|
33
|
+
return self.scanController.startScan()
|
|
34
|
+
}
|
|
35
|
+
Function("stopScan") {
|
|
36
|
+
self.scanController.stopScan()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// === USB — iOS 미지원
|
|
40
|
+
AsyncFunction("getUsbPrinterList") { () -> [[String: Any]] in [] }
|
|
41
|
+
AsyncFunction("requestUsbPermission") { (_: [String: Any]) -> Bool in false }
|
|
42
|
+
|
|
43
|
+
// === 연결 라이프사이클
|
|
44
|
+
AsyncFunction("connect") { (params: [String: Any]) -> Int in
|
|
45
|
+
let name = params["name"] as? String ?? ""
|
|
46
|
+
let macAddress = params["macAddress"] as? String ?? ""
|
|
47
|
+
let typeRaw = params["type"] as? Int ?? 0
|
|
48
|
+
let queueLabel = params["queueLabel"] as? String
|
|
49
|
+
|
|
50
|
+
let printer = NPrinter()
|
|
51
|
+
printer.setName(name)
|
|
52
|
+
_ = printer.setMacAddress(macAddress)
|
|
53
|
+
printer.setType(NPrinterType(rawValue: typeRaw) ?? .none)
|
|
54
|
+
|
|
55
|
+
let result = self.printerController.connect(printer, queueLabel: queueLabel)
|
|
56
|
+
if result == NemonicSdk.NResult.ok.rawValue {
|
|
57
|
+
self.connectedPrinter = printer
|
|
58
|
+
}
|
|
59
|
+
return result
|
|
60
|
+
}
|
|
61
|
+
Function("disconnect") {
|
|
62
|
+
self.printerController.disconnect()
|
|
63
|
+
self.connectedPrinter = nil
|
|
64
|
+
}
|
|
65
|
+
AsyncFunction("getConnectState") { () -> Int in
|
|
66
|
+
return self.printerController.getConnectState()
|
|
67
|
+
}
|
|
68
|
+
Function("cancel") {
|
|
69
|
+
self.printerController.cancel()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// === 인쇄
|
|
73
|
+
Function("setPrintTimeout") { (enableAuto: Bool, manualTime: Int) in
|
|
74
|
+
self.printerController.setPrintTimeout(enableAuto, manualTime)
|
|
75
|
+
}
|
|
76
|
+
AsyncFunction("print") { (params: [String: Any]) -> Int in
|
|
77
|
+
let imageData = params["images"] as? [[Int]] ?? []
|
|
78
|
+
let imageUrls = params["imageUrls"] as? [String] ?? []
|
|
79
|
+
|
|
80
|
+
for img in imageData where img.count > MAX_IMAGE_SIZE {
|
|
81
|
+
return EXCEED_MAX_SIZE
|
|
82
|
+
}
|
|
83
|
+
guard let printer = self.connectedPrinter else {
|
|
84
|
+
return -301 // NOT_CONNECTED
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
self.printSeq += 1
|
|
88
|
+
let seq = self.printSeq
|
|
89
|
+
let t0 = Date()
|
|
90
|
+
let elapsedMs: (Date) -> Int = { Int($0.timeIntervalSince(t0) * 1000) }
|
|
91
|
+
NSLog("[\(PRINT_TAG)] #\(seq) T+0ms ▶ print() entered (images=\(imageData.count), urls=\(imageUrls.count))")
|
|
92
|
+
|
|
93
|
+
let images = self.decodeImages(imageData: imageData, imageUrls: imageUrls)
|
|
94
|
+
let tDecoded = Date()
|
|
95
|
+
let firstSize = images.first.map { "\(Int($0.size.width))x\(Int($0.size.height))" } ?? "-"
|
|
96
|
+
NSLog("[\(PRINT_TAG)] #\(seq) T+\(elapsedMs(tDecoded))ms images decoded (count=\(images.count), size=\(firstSize))")
|
|
97
|
+
|
|
98
|
+
guard !images.isEmpty else {
|
|
99
|
+
return -501 // INVALID_PARAMETER
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
let qualityRaw = params["quality"] as? Int ?? 0
|
|
103
|
+
let copiesN = params["copies"] as? Int ?? 1
|
|
104
|
+
let cut = params["isLastPageCut"] as? Bool ?? true
|
|
105
|
+
let dither = params["enableDither"] as? Bool ?? true
|
|
106
|
+
let checkStatus = params["isCheckPrinterStatus"] as? Bool ?? true
|
|
107
|
+
let checkCart = params["isCheckCartridgeType"] as? Bool ?? true
|
|
108
|
+
let checkPower = params["isCheckPower"] as? Bool ?? true
|
|
109
|
+
|
|
110
|
+
let info = NPrintInfo(printer: printer, images: images)
|
|
111
|
+
_ = info
|
|
112
|
+
.setPrintQuality(NPrintQuality(rawValue: qualityRaw) ?? .lowFast)
|
|
113
|
+
.setCopies(copiesN)
|
|
114
|
+
.setEnableLastPageCut(cut)
|
|
115
|
+
.setEnableDither(dither)
|
|
116
|
+
.setEnableCheckPrinterStatus(checkStatus)
|
|
117
|
+
.setEnableCheckCartridgeType(checkCart)
|
|
118
|
+
.setEnableCheckPower(checkPower)
|
|
119
|
+
|
|
120
|
+
let tBeforeSdk = Date()
|
|
121
|
+
NSLog("[\(PRINT_TAG)] #\(seq) T+\(elapsedMs(tBeforeSdk))ms ▶ printerController.print() called (quality=\(qualityRaw), copies=\(copiesN), dither=\(dither), cut=\(cut), checkStatus=\(checkStatus), checkCart=\(checkCart), checkPower=\(checkPower))")
|
|
122
|
+
self.printStartedAt = tBeforeSdk
|
|
123
|
+
|
|
124
|
+
let result = self.printerController.print(info)
|
|
125
|
+
|
|
126
|
+
let tAfterSdk = Date()
|
|
127
|
+
let sdkMs = Int(tAfterSdk.timeIntervalSince(tBeforeSdk) * 1000)
|
|
128
|
+
NSLog("[\(PRINT_TAG)] #\(seq) T+\(elapsedMs(tAfterSdk))ms ◀ printerController.print() returned (result=\(result), sdkCall=\(sdkMs)ms)")
|
|
129
|
+
return result
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// === 템플릿
|
|
133
|
+
AsyncFunction("setTemplate") { (image: [Int], withPrint: Bool, enableDither: Bool) -> Int in
|
|
134
|
+
if image.count > MAX_IMAGE_SIZE { return EXCEED_MAX_SIZE }
|
|
135
|
+
let bytes = image.map { UInt8($0 & 0xff) }
|
|
136
|
+
let data = Data(bytes)
|
|
137
|
+
guard let uiImage = UIImage(data: data) else { return -501 }
|
|
138
|
+
return self.printerController.setTemplate(uiImage, withPrint: withPrint, enableDither: enableDither)
|
|
139
|
+
}
|
|
140
|
+
AsyncFunction("setTemplateWithUrl") { (imageUrl: String, withPrint: Bool, enableDither: Bool) -> Int in
|
|
141
|
+
guard let url = URL(string: imageUrl),
|
|
142
|
+
let data = try? Data(contentsOf: url),
|
|
143
|
+
let uiImage = UIImage(data: data) else { return -501 }
|
|
144
|
+
return self.printerController.setTemplate(uiImage, withPrint: withPrint, enableDither: enableDither)
|
|
145
|
+
}
|
|
146
|
+
AsyncFunction("clearTemplate") { () -> Int in
|
|
147
|
+
return self.printerController.clearTemplate()
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// === 상태
|
|
151
|
+
AsyncFunction("getPrinterStatus") { () -> Int in self.printerController.getPrinterStatus() }
|
|
152
|
+
AsyncFunction("getCartridgeType") { () -> Int in self.printerController.getCartridgeType() }
|
|
153
|
+
AsyncFunction("getPrinterName") { () -> [String: Any] in
|
|
154
|
+
let r = self.printerController.getPrinterName()
|
|
155
|
+
return ["result": r.getResult(), "value": r.getValue()]
|
|
156
|
+
}
|
|
157
|
+
AsyncFunction("getBatteryLevel") { () -> Int in self.printerController.getBatteryLevel() }
|
|
158
|
+
AsyncFunction("getBatteryStatus") { () -> Int in self.printerController.getBatteryStatus() }
|
|
159
|
+
|
|
160
|
+
// === Android BLE 딜레이 stub
|
|
161
|
+
AsyncFunction("getBleConnectDelayOffset") { () -> Int in 0 }
|
|
162
|
+
Function("setBleConnectDelayOffset") { (_: Int) in }
|
|
163
|
+
AsyncFunction("getBleSendRetryDelayOffset") { () -> Int in 0 }
|
|
164
|
+
Function("setBleSendRetryDelayOffset") { (_: Int) in }
|
|
165
|
+
|
|
166
|
+
// === iOS connect delay
|
|
167
|
+
AsyncFunction("getDefaultConnectDelay") { () -> Int in
|
|
168
|
+
return Int(self.printerController.getDefaultConnectDelay())
|
|
169
|
+
}
|
|
170
|
+
AsyncFunction("getConnectDelay") { () -> Int in
|
|
171
|
+
return Int(self.printerController.getConnectDelay())
|
|
172
|
+
}
|
|
173
|
+
Function("setConnectDelay") { (msec: Int) in
|
|
174
|
+
self.printerController.setConnectDelay(UInt32(msec))
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
private var delegateRef: BootNemonicPrinterDelegate?
|
|
179
|
+
|
|
180
|
+
fileprivate func emitDisconnected() {
|
|
181
|
+
sendEvent("onDisconnected", [:])
|
|
182
|
+
}
|
|
183
|
+
fileprivate func emitPrintProgress(index: Int, total: Int, result: Int) {
|
|
184
|
+
let elapsed = printStartedAt.map { Int(Date().timeIntervalSince($0) * 1000) } ?? -1
|
|
185
|
+
NSLog("[\(PRINT_TAG)] #\(printSeq) T+\(elapsed)ms · printProgress index=\(index)/\(total) result=\(result)")
|
|
186
|
+
sendEvent("onPrintProgress", ["index": index, "total": total, "result": result])
|
|
187
|
+
}
|
|
188
|
+
fileprivate func emitPrintComplete(result: Int) {
|
|
189
|
+
let elapsed = printStartedAt.map { Int(Date().timeIntervalSince($0) * 1000) } ?? -1
|
|
190
|
+
NSLog("[\(PRINT_TAG)] #\(printSeq) T+\(elapsed)ms ✓ printComplete result=\(result)")
|
|
191
|
+
sendEvent("onPrintComplete", ["result": result])
|
|
192
|
+
}
|
|
193
|
+
fileprivate func emitDeviceFound(_ printer: NPrinter) {
|
|
194
|
+
let type = printer.getType()
|
|
195
|
+
sendEvent("onDeviceFound", [
|
|
196
|
+
"name": printer.getName(),
|
|
197
|
+
"macAddress": printer.getMacAddress(),
|
|
198
|
+
"type": type.rawValue,
|
|
199
|
+
"typeName": printerTypeName(type),
|
|
200
|
+
"transport": "bluetooth",
|
|
201
|
+
])
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// SDK 의 NPrinterType 은 Obj-C NS_ENUM 으로 노출돼 String(describing:) 결과가
|
|
205
|
+
// "NPrinterType(rawValue: N)" 으로 나옴. Android SDK 의 enum.toString() 이 반환하는
|
|
206
|
+
// 사람 친화적 표시명 ("Nemonic AI" 등) 과 맞추기 위해 명시적으로 매핑.
|
|
207
|
+
// (표시명 출처: NemonicSdk-Swift.h 의 NPrinterType doc-comment.)
|
|
208
|
+
private func printerTypeName(_ type: NPrinterType) -> String {
|
|
209
|
+
switch type {
|
|
210
|
+
case .none: return "None"
|
|
211
|
+
case .nemonic: return "Nemonic"
|
|
212
|
+
case .nemonicLabel: return "Nemonic Label"
|
|
213
|
+
case .nemonicMini: return "Nemonic mini"
|
|
214
|
+
case .nemonicMip201: return "Nemonic AI"
|
|
215
|
+
@unknown default: return "Unknown(\(type.rawValue))"
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private func decodeImages(imageData: [[Int]], imageUrls: [String]) -> [UIImage] {
|
|
220
|
+
var result: [UIImage] = []
|
|
221
|
+
if !imageData.isEmpty {
|
|
222
|
+
for arr in imageData {
|
|
223
|
+
let bytes = arr.map { UInt8($0 & 0xff) }
|
|
224
|
+
let data = Data(bytes)
|
|
225
|
+
if let image = UIImage(data: data) {
|
|
226
|
+
result.append(image)
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
} else {
|
|
230
|
+
for urlString in imageUrls {
|
|
231
|
+
guard let url = URL(string: urlString),
|
|
232
|
+
let data = try? Data(contentsOf: url),
|
|
233
|
+
let image = UIImage(data: data) else { continue }
|
|
234
|
+
result.append(image)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return result
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private class BootNemonicPrinterDelegate: NSObject, NPrinterControllerDelegate, NPrinterScanControllerDelegate {
|
|
242
|
+
weak var owner: BootNemonicPrinterModule?
|
|
243
|
+
init(owner: BootNemonicPrinterModule) { self.owner = owner }
|
|
244
|
+
|
|
245
|
+
func disconnected() {
|
|
246
|
+
owner?.emitDisconnected()
|
|
247
|
+
}
|
|
248
|
+
func printProgress(index: Int, total: Int, result: Int) {
|
|
249
|
+
owner?.emitPrintProgress(index: index, total: total, result: result)
|
|
250
|
+
}
|
|
251
|
+
func printComplete(result: Int) {
|
|
252
|
+
owner?.emitPrintComplete(result: result)
|
|
253
|
+
}
|
|
254
|
+
func deviceFound(_ printer: NPrinter) {
|
|
255
|
+
owner?.emitDeviceFound(printer)
|
|
256
|
+
}
|
|
257
|
+
}
|