seven365-zyprinter 0.0.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/Package.swift +43 -0
- package/README.md +186 -0
- package/Seven365Zyprinter.podspec +27 -0
- package/android/build.gradle +58 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/mycompany/plugins/example/Example.java +342 -0
- package/android/src/main/java/com/mycompany/plugins/example/ExamplePlugin.java +161 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +229 -0
- package/dist/esm/definitions.d.ts +56 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +49 -0
- package/dist/esm/web.js +40 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +54 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +57 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Seven365Zyprinter.podspec +28 -0
- package/ios/Sources/Plugin/ZyprintPlugin.swift +161 -0
- package/ios/Sources/Plugin/ZywellSDK.swift +358 -0
- package/ios/Sources/Seven365Zyprinter-Umbrella.h +16 -0
- package/ios/Sources/module.modulemap +12 -0
- package/ios/Sources/sources/BLEManager.h +658 -0
- package/ios/Sources/sources/BLEManager.m +2842 -0
- package/ios/Sources/sources/GCD/Documentation.html +47 -0
- package/ios/Sources/sources/GCD/GCDAsyncSocket.h +1226 -0
- package/ios/Sources/sources/GCD/GCDAsyncSocket.m +8560 -0
- package/ios/Sources/sources/GCD/GCDAsyncUdpSocket.h +1036 -0
- package/ios/Sources/sources/GCD/GCDAsyncUdpSocket.m +5632 -0
- package/ios/Sources/sources/GCD/PrinterManager.h +91 -0
- package/ios/Sources/sources/GCD/PrinterManager.m +513 -0
- package/ios/Sources/sources/GCD/WifiManager.h +91 -0
- package/ios/Sources/sources/GCD/WifiManager.m +510 -0
- package/ios/Sources/sources/ImageTranster.h +38 -0
- package/ios/Sources/sources/ImageTranster.m +389 -0
- package/ios/Sources/sources/POSBLEManager.h +759 -0
- package/ios/Sources/sources/POSBLEManager.m +834 -0
- package/ios/Sources/sources/POSSDK.h +93 -0
- package/ios/Sources/sources/POSWIFIManager.h +116 -0
- package/ios/Sources/sources/POSWIFIManager.m +260 -0
- package/ios/Sources/sources/POSWIFIManagerAsync.h +745 -0
- package/ios/Sources/sources/POSWIFIManagerAsync.m +1847 -0
- package/ios/Sources/sources/PosCommand.h +633 -0
- package/ios/Sources/sources/PosCommand.m +1019 -0
- package/ios/Sources/sources/TscCommand.h +723 -0
- package/ios/Sources/sources/TscCommand.m +566 -0
- package/ios/Tests/ExamplePluginTests/ExamplePluginTests.swift +15 -0
- package/package.json +339 -0
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
var capacitorExample = (function (exports, core) {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const Zyprint = core.registerPlugin('Zyprint', {
|
|
5
|
+
web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.ZyprintWeb()),
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
class ZyprintWeb extends core.WebPlugin {
|
|
9
|
+
async echo(options) {
|
|
10
|
+
console.log('ECHO', options);
|
|
11
|
+
return options;
|
|
12
|
+
}
|
|
13
|
+
async discoverPrinters() {
|
|
14
|
+
console.warn('Zyprint discovery is not available on web platform');
|
|
15
|
+
return { printers: [] };
|
|
16
|
+
}
|
|
17
|
+
async discoverBluetoothPrinters() {
|
|
18
|
+
console.warn('Zyprint Bluetooth discovery is not available on web platform');
|
|
19
|
+
return { printers: [] };
|
|
20
|
+
}
|
|
21
|
+
async discoverWiFiPrinters(_options) {
|
|
22
|
+
console.warn('Zyprint WiFi discovery is not available on web platform');
|
|
23
|
+
return { printers: [] };
|
|
24
|
+
}
|
|
25
|
+
async connectToPrinter(_options) {
|
|
26
|
+
console.warn('Zyprint connection is not available on web platform');
|
|
27
|
+
return { connected: false };
|
|
28
|
+
}
|
|
29
|
+
async disconnectFromPrinter(_options) {
|
|
30
|
+
console.warn('Zyprint disconnection is not available on web platform');
|
|
31
|
+
return { disconnected: false };
|
|
32
|
+
}
|
|
33
|
+
async printText(_options) {
|
|
34
|
+
console.warn('Zyprint printing is not available on web platform');
|
|
35
|
+
return { success: false };
|
|
36
|
+
}
|
|
37
|
+
async printReceipt(_options) {
|
|
38
|
+
console.warn('Zyprint receipt printing is not available on web platform');
|
|
39
|
+
return { success: false };
|
|
40
|
+
}
|
|
41
|
+
async getPrinterStatus(_options) {
|
|
42
|
+
console.warn('Zyprint status check is not available on web platform');
|
|
43
|
+
return { status: 'unknown', paperStatus: 'unknown', connected: false };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
var web = /*#__PURE__*/Object.freeze({
|
|
48
|
+
__proto__: null,
|
|
49
|
+
ZyprintWeb: ZyprintWeb
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
exports.Zyprint = Zyprint;
|
|
53
|
+
|
|
54
|
+
return exports;
|
|
55
|
+
|
|
56
|
+
})({}, capacitorExports);
|
|
57
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Zyprint = registerPlugin('Zyprint', {\n web: () => import('./web').then((m) => new m.ZyprintWeb()),\n});\nexport * from './definitions';\nexport { Zyprint };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class ZyprintWeb extends WebPlugin {\n async echo(options) {\n console.log('ECHO', options);\n return options;\n }\n async discoverPrinters() {\n console.warn('Zyprint discovery is not available on web platform');\n return { printers: [] };\n }\n async discoverBluetoothPrinters() {\n console.warn('Zyprint Bluetooth discovery is not available on web platform');\n return { printers: [] };\n }\n async discoverWiFiPrinters(_options) {\n console.warn('Zyprint WiFi discovery is not available on web platform');\n return { printers: [] };\n }\n async connectToPrinter(_options) {\n console.warn('Zyprint connection is not available on web platform');\n return { connected: false };\n }\n async disconnectFromPrinter(_options) {\n console.warn('Zyprint disconnection is not available on web platform');\n return { disconnected: false };\n }\n async printText(_options) {\n console.warn('Zyprint printing is not available on web platform');\n return { success: false };\n }\n async printReceipt(_options) {\n console.warn('Zyprint receipt printing is not available on web platform');\n return { success: false };\n }\n async getPrinterStatus(_options) {\n console.warn('Zyprint status check is not available on web platform');\n return { status: 'unknown', paperStatus: 'unknown', connected: false };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,OAAO,GAAGA,mBAAc,CAAC,SAAS,EAAE;IAC1C,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;IAC9D,CAAC;;ICFM,MAAM,UAAU,SAASC,cAAS,CAAC;IAC1C,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;IACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IACpC,QAAQ,OAAO,OAAO;IACtB,IAAI;IACJ,IAAI,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,OAAO,CAAC,IAAI,CAAC,oDAAoD,CAAC;IAC1E,QAAQ,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC/B,IAAI;IACJ,IAAI,MAAM,yBAAyB,GAAG;IACtC,QAAQ,OAAO,CAAC,IAAI,CAAC,8DAA8D,CAAC;IACpF,QAAQ,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC/B,IAAI;IACJ,IAAI,MAAM,oBAAoB,CAAC,QAAQ,EAAE;IACzC,QAAQ,OAAO,CAAC,IAAI,CAAC,yDAAyD,CAAC;IAC/E,QAAQ,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC/B,IAAI;IACJ,IAAI,MAAM,gBAAgB,CAAC,QAAQ,EAAE;IACrC,QAAQ,OAAO,CAAC,IAAI,CAAC,qDAAqD,CAAC;IAC3E,QAAQ,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE;IACnC,IAAI;IACJ,IAAI,MAAM,qBAAqB,CAAC,QAAQ,EAAE;IAC1C,QAAQ,OAAO,CAAC,IAAI,CAAC,wDAAwD,CAAC;IAC9E,QAAQ,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE;IACtC,IAAI;IACJ,IAAI,MAAM,SAAS,CAAC,QAAQ,EAAE;IAC9B,QAAQ,OAAO,CAAC,IAAI,CAAC,mDAAmD,CAAC;IACzE,QAAQ,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE;IACjC,IAAI;IACJ,IAAI,MAAM,YAAY,CAAC,QAAQ,EAAE;IACjC,QAAQ,OAAO,CAAC,IAAI,CAAC,2DAA2D,CAAC;IACjF,QAAQ,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE;IACjC,IAAI;IACJ,IAAI,MAAM,gBAAgB,CAAC,QAAQ,EAAE;IACrC,QAAQ,OAAO,CAAC,IAAI,CAAC,uDAAuD,CAAC;IAC7E,QAAQ,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE;IAC9E,IAAI;IACJ;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = 'Seven365Zyprinter'
|
|
7
|
+
s.version = package['version']
|
|
8
|
+
s.summary = package['description']
|
|
9
|
+
s.license = package['license']
|
|
10
|
+
s.homepage = package['repository']['url']
|
|
11
|
+
s.author = package['author']
|
|
12
|
+
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
|
|
13
|
+
# Source files include Swift and Objective-C source from ios/Sources
|
|
14
|
+
s.source_files = 'ios/Sources/**/*.{swift,h,m,mm,c,cc,cpp}'
|
|
15
|
+
s.ios.deployment_target = '14.0'
|
|
16
|
+
s.dependency 'Capacitor'
|
|
17
|
+
s.swift_version = '5.1'
|
|
18
|
+
|
|
19
|
+
# iOS system frameworks required for Zyprint functionality
|
|
20
|
+
# CoreBluetooth for BLE, SystemConfiguration/CFNetwork for networking
|
|
21
|
+
s.frameworks = 'CoreBluetooth', 'SystemConfiguration', 'CFNetwork'
|
|
22
|
+
|
|
23
|
+
# Expose Zywell SDK public headers so consumers can import Objective-C APIs
|
|
24
|
+
s.public_header_files = 'ios/Sources/zywell/ZywellSDK/**/*.h'
|
|
25
|
+
|
|
26
|
+
# Uncomment when you add the Zywell SDK framework:
|
|
27
|
+
# s.vendored_frameworks = 'Frameworks/ZywellPrinter.xcframework'
|
|
28
|
+
end
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ZyprintPlugin.swift
|
|
3
|
+
// Seven365Zyprinter
|
|
4
|
+
//
|
|
5
|
+
// Capacitor plugin for Zywell thermal printer integration
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import Capacitor
|
|
10
|
+
|
|
11
|
+
@objc(ZyprintPlugin)
|
|
12
|
+
public class ZyprintPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
13
|
+
public let identifier = "ZyprintPlugin"
|
|
14
|
+
public let jsName = "Zyprint"
|
|
15
|
+
public let pluginMethods: [CAPPluginMethod] = [
|
|
16
|
+
CAPPluginMethod(name: "echo", returnType: CAPPluginReturnPromise),
|
|
17
|
+
CAPPluginMethod(name: "discoverPrinters", returnType: CAPPluginReturnPromise),
|
|
18
|
+
CAPPluginMethod(name: "discoverBluetoothPrinters", returnType: CAPPluginReturnPromise),
|
|
19
|
+
CAPPluginMethod(name: "discoverWiFiPrinters", returnType: CAPPluginReturnPromise),
|
|
20
|
+
CAPPluginMethod(name: "connectToPrinter", returnType: CAPPluginReturnPromise),
|
|
21
|
+
CAPPluginMethod(name: "disconnectFromPrinter", returnType: CAPPluginReturnPromise),
|
|
22
|
+
CAPPluginMethod(name: "printText", returnType: CAPPluginReturnPromise),
|
|
23
|
+
CAPPluginMethod(name: "printReceipt", returnType: CAPPluginReturnPromise),
|
|
24
|
+
CAPPluginMethod(name: "getPrinterStatus", returnType: CAPPluginReturnPromise)
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
private let implementation = ZywellSDK()
|
|
28
|
+
|
|
29
|
+
@objc func echo(_ call: CAPPluginCall) {
|
|
30
|
+
let value = call.getString("value") ?? ""
|
|
31
|
+
call.resolve([
|
|
32
|
+
"value": implementation.echo(value)
|
|
33
|
+
])
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@objc func discoverPrinters(_ call: CAPPluginCall) {
|
|
37
|
+
implementation.discoverPrinters { printers, error in
|
|
38
|
+
if let error = error {
|
|
39
|
+
call.reject(error)
|
|
40
|
+
} else {
|
|
41
|
+
call.resolve([
|
|
42
|
+
"printers": printers
|
|
43
|
+
])
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@objc func discoverBluetoothPrinters(_ call: CAPPluginCall) {
|
|
49
|
+
implementation.discoverBluetoothPrinters { printers, error in
|
|
50
|
+
if let error = error {
|
|
51
|
+
call.reject(error)
|
|
52
|
+
} else {
|
|
53
|
+
call.resolve([
|
|
54
|
+
"printers": printers
|
|
55
|
+
])
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@objc func discoverWiFiPrinters(_ call: CAPPluginCall) {
|
|
61
|
+
let networkRange = call.getString("networkRange")
|
|
62
|
+
implementation.discoverWiFiPrinters(networkRange: networkRange) { printers, error in
|
|
63
|
+
if let error = error {
|
|
64
|
+
call.reject(error)
|
|
65
|
+
} else {
|
|
66
|
+
call.resolve([
|
|
67
|
+
"printers": printers
|
|
68
|
+
])
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@objc func connectToPrinter(_ call: CAPPluginCall) {
|
|
74
|
+
guard let identifier = call.getString("identifier") else {
|
|
75
|
+
call.reject("Missing identifier parameter")
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
implementation.connectToPrinter(identifier: identifier) { success, error in
|
|
80
|
+
if let error = error {
|
|
81
|
+
call.reject(error)
|
|
82
|
+
} else {
|
|
83
|
+
call.resolve([
|
|
84
|
+
"connected": success
|
|
85
|
+
])
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@objc func disconnectFromPrinter(_ call: CAPPluginCall) {
|
|
91
|
+
guard let identifier = call.getString("identifier") else {
|
|
92
|
+
call.reject("Missing identifier parameter")
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
implementation.disconnectFromPrinter(identifier: identifier) { success, error in
|
|
97
|
+
if let error = error {
|
|
98
|
+
call.reject(error)
|
|
99
|
+
} else {
|
|
100
|
+
call.resolve([
|
|
101
|
+
"disconnected": success
|
|
102
|
+
])
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@objc func printText(_ call: CAPPluginCall) {
|
|
108
|
+
guard let text = call.getString("text"),
|
|
109
|
+
let identifier = call.getString("identifier") else {
|
|
110
|
+
call.reject("Missing required parameters")
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
implementation.printText(text: text, identifier: identifier) { success, error in
|
|
115
|
+
if let error = error {
|
|
116
|
+
call.reject(error)
|
|
117
|
+
} else {
|
|
118
|
+
call.resolve([
|
|
119
|
+
"success": success
|
|
120
|
+
])
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@objc func printReceipt(_ call: CAPPluginCall) {
|
|
126
|
+
guard let template = call.getObject("template"),
|
|
127
|
+
let identifier = call.getString("identifier") else {
|
|
128
|
+
call.reject("Missing required parameters")
|
|
129
|
+
return
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
implementation.printReceipt(template: template, identifier: identifier) { success, error in
|
|
133
|
+
if let error = error {
|
|
134
|
+
call.reject(error)
|
|
135
|
+
} else {
|
|
136
|
+
call.resolve([
|
|
137
|
+
"success": success
|
|
138
|
+
])
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@objc func getPrinterStatus(_ call: CAPPluginCall) {
|
|
144
|
+
guard let identifier = call.getString("identifier") else {
|
|
145
|
+
call.reject("Missing identifier parameter")
|
|
146
|
+
return
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
implementation.getPrinterStatus(identifier: identifier) { status, paperStatus, connected, error in
|
|
150
|
+
if let error = error {
|
|
151
|
+
call.reject(error)
|
|
152
|
+
} else {
|
|
153
|
+
call.resolve([
|
|
154
|
+
"status": status,
|
|
155
|
+
"paperStatus": paperStatus,
|
|
156
|
+
"connected": connected
|
|
157
|
+
])
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ZywellSDK.swift
|
|
3
|
+
// Seven365Zyprinter
|
|
4
|
+
//
|
|
5
|
+
// Swift wrapper for the Zywell Objective-C SDK
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import CoreBluetooth
|
|
10
|
+
|
|
11
|
+
@objc public class ZywellSDK: NSObject {
|
|
12
|
+
|
|
13
|
+
private var bleManager: POSBLEManager?
|
|
14
|
+
private var wifiManagers: [String: POSWIFIManager] = [:]
|
|
15
|
+
private var discoveredPeripherals: [CBPeripheral] = []
|
|
16
|
+
private var peripheralRSSIs: [NSNumber] = []
|
|
17
|
+
|
|
18
|
+
public override init() {
|
|
19
|
+
super.init()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// MARK: - Echo Test
|
|
23
|
+
|
|
24
|
+
@objc public func echo(_ value: String) -> String {
|
|
25
|
+
return value
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// MARK: - Printer Discovery
|
|
29
|
+
|
|
30
|
+
@objc public func discoverPrinters(completion: @escaping ([[String: Any]], String?) -> Void) {
|
|
31
|
+
// Discover both Bluetooth and WiFi printers
|
|
32
|
+
var allPrinters: [[String: Any]] = []
|
|
33
|
+
let group = DispatchGroup()
|
|
34
|
+
|
|
35
|
+
// Discover Bluetooth
|
|
36
|
+
group.enter()
|
|
37
|
+
discoverBluetoothPrinters { btPrinters, error in
|
|
38
|
+
if error == nil {
|
|
39
|
+
allPrinters.append(contentsOf: btPrinters)
|
|
40
|
+
}
|
|
41
|
+
group.leave()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Discover WiFi
|
|
45
|
+
group.enter()
|
|
46
|
+
discoverWiFiPrinters(networkRange: nil) { wifiPrinters, error in
|
|
47
|
+
if error == nil {
|
|
48
|
+
allPrinters.append(contentsOf: wifiPrinters)
|
|
49
|
+
}
|
|
50
|
+
group.leave()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
group.notify(queue: .main) {
|
|
54
|
+
completion(allPrinters, nil)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@objc public func discoverBluetoothPrinters(completion: @escaping ([[String: Any]], String?) -> Void) {
|
|
59
|
+
bleManager = POSBLEManager.sharedInstance()
|
|
60
|
+
bleManager?.delegate = self
|
|
61
|
+
|
|
62
|
+
// Store completion for delegate callback
|
|
63
|
+
self.discoveryCompletion = completion
|
|
64
|
+
|
|
65
|
+
// Start scanning
|
|
66
|
+
bleManager?.poSstartScan()
|
|
67
|
+
|
|
68
|
+
// Auto-stop after 5 seconds
|
|
69
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { [weak self] in
|
|
70
|
+
self?.bleManager?.poSstopScan()
|
|
71
|
+
|
|
72
|
+
guard let printers = self?.discoveredPeripherals,
|
|
73
|
+
let rssis = self?.peripheralRSSIs else {
|
|
74
|
+
completion([], nil)
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
var printerList: [[String: Any]] = []
|
|
79
|
+
for (index, peripheral) in printers.enumerated() {
|
|
80
|
+
let rssi = rssis.count > index ? rssis[index].intValue : 0
|
|
81
|
+
|
|
82
|
+
printerList.append([
|
|
83
|
+
"identifier": peripheral.identifier.uuidString,
|
|
84
|
+
"model": peripheral.name ?? "Unknown Printer",
|
|
85
|
+
"status": "ready",
|
|
86
|
+
"connectionType": "bluetooth",
|
|
87
|
+
"rssi": rssi
|
|
88
|
+
])
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
completion(printerList, nil)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@objc public func discoverWiFiPrinters(networkRange: String?, completion: @escaping ([[String: Any]], String?) -> Void) {
|
|
96
|
+
// For WiFi discovery, we would need to implement network scanning
|
|
97
|
+
// This is a placeholder - WiFi printers typically need manual IP entry
|
|
98
|
+
// or use mDNS/Bonjour discovery which requires additional implementation
|
|
99
|
+
|
|
100
|
+
// Return empty for now - users will connect via IP address
|
|
101
|
+
completion([], nil)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// MARK: - Connection Management
|
|
105
|
+
|
|
106
|
+
@objc public func connectToPrinter(identifier: String, completion: @escaping (Bool, String?) -> Void) {
|
|
107
|
+
// Check if it's a Bluetooth connection (UUID format)
|
|
108
|
+
if let uuid = UUID(uuidString: identifier) {
|
|
109
|
+
connectBluetoothPrinter(uuid: uuid, completion: completion)
|
|
110
|
+
} else {
|
|
111
|
+
// Assume it's an IP address for WiFi
|
|
112
|
+
connectWiFiPrinter(ipAddress: identifier, completion: completion)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private func connectBluetoothPrinter(uuid: UUID, completion: @escaping (Bool, String?) -> Void) {
|
|
117
|
+
if bleManager == nil {
|
|
118
|
+
bleManager = POSBLEManager.sharedInstance()
|
|
119
|
+
bleManager?.delegate = self
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
guard let manager = bleManager else {
|
|
123
|
+
completion(false, "Failed to initialize BLE manager")
|
|
124
|
+
return
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Find the peripheral
|
|
128
|
+
guard let peripheral = discoveredPeripherals.first(where: { $0.identifier == uuid }) else {
|
|
129
|
+
completion(false, "Printer not found")
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
self.connectionCompletion = completion
|
|
134
|
+
manager.poSconnectDevice(peripheral)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private func connectWiFiPrinter(ipAddress: String, completion: @escaping (Bool, String?) -> Void) {
|
|
138
|
+
let port: UInt16 = 9100 // Standard printer port
|
|
139
|
+
|
|
140
|
+
let wifiManager = POSWIFIManager()
|
|
141
|
+
wifiManager.delegate = self
|
|
142
|
+
wifiManagers[ipAddress] = wifiManager
|
|
143
|
+
|
|
144
|
+
self.connectionCompletion = completion
|
|
145
|
+
|
|
146
|
+
wifiManager.posConnect(withHost: ipAddress, port: port) { [weak self] isConnected in
|
|
147
|
+
completion(isConnected, isConnected ? nil : "Connection failed")
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@objc public func disconnectFromPrinter(identifier: String, completion: @escaping (Bool, String?) -> Void) {
|
|
152
|
+
// Check if it's WiFi connection
|
|
153
|
+
if let wifiManager = wifiManagers[identifier] {
|
|
154
|
+
wifiManager.posDisConnect()
|
|
155
|
+
wifiManagers.removeValue(forKey: identifier)
|
|
156
|
+
completion(true, nil)
|
|
157
|
+
} else {
|
|
158
|
+
// Bluetooth disconnection
|
|
159
|
+
bleManager?.poSdisconnectRootPeripheral()
|
|
160
|
+
completion(true, nil)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// MARK: - Printing Methods
|
|
165
|
+
|
|
166
|
+
@objc public func printText(text: String, identifier: String, completion: @escaping (Bool, String?) -> Void) {
|
|
167
|
+
guard let data = formatTextForPrinter(text: text) else {
|
|
168
|
+
completion(false, "Failed to format text")
|
|
169
|
+
return
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
sendDataToPrinter(data: data, identifier: identifier, completion: completion)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@objc public func printReceipt(template: [String: Any], identifier: String, completion: @escaping (Bool, String?) -> Void) {
|
|
176
|
+
guard let data = formatReceiptForPrinter(template: template) else {
|
|
177
|
+
completion(false, "Failed to format receipt")
|
|
178
|
+
return
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
sendDataToPrinter(data: data, identifier: identifier, completion: completion)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private func sendDataToPrinter(data: Data, identifier: String, completion: @escaping (Bool, String?) -> Void) {
|
|
185
|
+
// Check if WiFi connection
|
|
186
|
+
if let wifiManager = wifiManagers[identifier] {
|
|
187
|
+
self.printCompletion = completion
|
|
188
|
+
wifiManager.posWriteCommand(with: data)
|
|
189
|
+
} else {
|
|
190
|
+
// Bluetooth connection
|
|
191
|
+
self.printCompletion = completion
|
|
192
|
+
bleManager?.posWriteCommand(with: data)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// MARK: - Printer Status
|
|
197
|
+
|
|
198
|
+
@objc public func getPrinterStatus(identifier: String, completion: @escaping (String, String, Bool, String?) -> Void) {
|
|
199
|
+
// Send status request command
|
|
200
|
+
let statusCommand = Data([0x10, 0x04, 0x01]) // DLE EOT n
|
|
201
|
+
|
|
202
|
+
if let wifiManager = wifiManagers[identifier] {
|
|
203
|
+
if wifiManager.isConnected {
|
|
204
|
+
completion("ready", "ok", true, nil)
|
|
205
|
+
} else {
|
|
206
|
+
completion("offline", "unknown", false, nil)
|
|
207
|
+
}
|
|
208
|
+
} else if let bleManager = bleManager, bleManager.connectOK {
|
|
209
|
+
completion("ready", "ok", true, nil)
|
|
210
|
+
} else {
|
|
211
|
+
completion("offline", "unknown", false, nil)
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// MARK: - Data Formatting
|
|
216
|
+
|
|
217
|
+
private func formatTextForPrinter(text: String) -> Data? {
|
|
218
|
+
var printData = Data()
|
|
219
|
+
|
|
220
|
+
// Initialize printer (ESC @)
|
|
221
|
+
printData.append(Data([0x1B, 0x40]))
|
|
222
|
+
|
|
223
|
+
// Add text
|
|
224
|
+
if let textData = text.data(using: .utf8) {
|
|
225
|
+
printData.append(textData)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Line feeds
|
|
229
|
+
printData.append(Data([0x0A, 0x0A, 0x0A]))
|
|
230
|
+
|
|
231
|
+
// Cut paper (GS V m)
|
|
232
|
+
printData.append(Data([0x1D, 0x56, 0x41, 0x10]))
|
|
233
|
+
|
|
234
|
+
return printData
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private func formatReceiptForPrinter(template: [String: Any]) -> Data? {
|
|
238
|
+
var printData = Data()
|
|
239
|
+
|
|
240
|
+
// Initialize printer
|
|
241
|
+
printData.append(Data([0x1B, 0x40]))
|
|
242
|
+
|
|
243
|
+
// Center align (ESC a 1)
|
|
244
|
+
printData.append(Data([0x1B, 0x61, 0x01]))
|
|
245
|
+
|
|
246
|
+
// Header
|
|
247
|
+
if let header = template["header"] as? String,
|
|
248
|
+
let headerData = (header + "\n\n").data(using: .utf8) {
|
|
249
|
+
printData.append(headerData)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Left align (ESC a 0)
|
|
253
|
+
printData.append(Data([0x1B, 0x61, 0x00]))
|
|
254
|
+
|
|
255
|
+
// Items
|
|
256
|
+
if let items = template["items"] as? [[String: Any]] {
|
|
257
|
+
for item in items {
|
|
258
|
+
if let name = item["name"] as? String,
|
|
259
|
+
let price = item["price"] as? String {
|
|
260
|
+
let line = String(format: "%@\t%@\n", name, price)
|
|
261
|
+
if let lineData = line.data(using: .utf8) {
|
|
262
|
+
printData.append(lineData)
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Total
|
|
269
|
+
if let total = template["total"] as? String,
|
|
270
|
+
let totalData = ("\nTotal: " + total + "\n").data(using: .utf8) {
|
|
271
|
+
printData.append(totalData)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Footer
|
|
275
|
+
if let footer = template["footer"] as? String,
|
|
276
|
+
let footerData = (footer + "\n").data(using: .utf8) {
|
|
277
|
+
printData.append(footerData)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Line feeds
|
|
281
|
+
printData.append(Data([0x0A, 0x0A, 0x0A]))
|
|
282
|
+
|
|
283
|
+
// Cut paper
|
|
284
|
+
printData.append(Data([0x1D, 0x56, 0x41, 0x10]))
|
|
285
|
+
|
|
286
|
+
return printData
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// MARK: - Callback Storage
|
|
290
|
+
|
|
291
|
+
private var discoveryCompletion: (([[String: Any]], String?) -> Void)?
|
|
292
|
+
private var connectionCompletion: ((Bool, String?) -> Void)?
|
|
293
|
+
private var printCompletion: ((Bool, String?) -> Void)?
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// MARK: - POSBLEManagerDelegate
|
|
297
|
+
|
|
298
|
+
extension ZywellSDK: POSBLEManagerDelegate {
|
|
299
|
+
|
|
300
|
+
public func poSdidUpdatePeripheralList(_ peripherals: [Any]!, rssiList: [Any]!) {
|
|
301
|
+
guard let peripherals = peripherals as? [CBPeripheral],
|
|
302
|
+
let rssis = rssiList as? [NSNumber] else { return }
|
|
303
|
+
|
|
304
|
+
self.discoveredPeripherals = peripherals
|
|
305
|
+
self.peripheralRSSIs = rssis
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
public func poSdidConnect(_ peripheral: CBPeripheral!) {
|
|
309
|
+
connectionCompletion?(true, nil)
|
|
310
|
+
connectionCompletion = nil
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
public func poSdidFail(toConnect peripheral: CBPeripheral!, error: Error!) {
|
|
314
|
+
let errorMsg = error?.localizedDescription ?? "Connection failed"
|
|
315
|
+
connectionCompletion?(false, errorMsg)
|
|
316
|
+
connectionCompletion = nil
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
public func poSdidDisconnectPeripheral(_ peripheral: CBPeripheral!, isAutoDisconnect: Bool) {
|
|
320
|
+
// Handle disconnection
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
public func poSdidWriteValue(for character: CBCharacteristic!, error: Error!) {
|
|
324
|
+
if let error = error {
|
|
325
|
+
printCompletion?(false, error.localizedDescription)
|
|
326
|
+
} else {
|
|
327
|
+
printCompletion?(true, nil)
|
|
328
|
+
}
|
|
329
|
+
printCompletion = nil
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// MARK: - POSWIFIManagerDelegate
|
|
334
|
+
|
|
335
|
+
extension ZywellSDK: POSWIFIManagerDelegate {
|
|
336
|
+
|
|
337
|
+
public func poswifiManager(_ manager: POSWIFIManager!, didConnectedToHost host: String!, port: UInt16) {
|
|
338
|
+
connectionCompletion?(true, nil)
|
|
339
|
+
connectionCompletion = nil
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
public func poswifiManager(_ manager: POSWIFIManager, willDisconnectWithError error: Error?) {
|
|
343
|
+
// Handle disconnection warning
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
public func poswifiManager(_ manager: POSWIFIManager!, didWriteDataWithTag tag: Int) {
|
|
347
|
+
printCompletion?(true, nil)
|
|
348
|
+
printCompletion = nil
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
public func poswifiManager(_ manager: POSWIFIManager, didRead data: Data, tag: Int) {
|
|
352
|
+
// Handle data reading if needed
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
public func poswifiManagerDidDisconnected(_ manager: POSWIFIManager!) {
|
|
356
|
+
// Handle disconnection
|
|
357
|
+
}
|
|
358
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Seven365Zyprinter-Umbrella.h
|
|
3
|
+
// Seven365Zyprinter
|
|
4
|
+
//
|
|
5
|
+
// Umbrella header for Zywell SDK Objective-C headers
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#import <Foundation/Foundation.h>
|
|
9
|
+
|
|
10
|
+
// Zywell SDK Headers
|
|
11
|
+
#import "POSSDK.h"
|
|
12
|
+
#import "POSBLEManager.h"
|
|
13
|
+
#import "POSWIFIManager.h"
|
|
14
|
+
#import "PosCommand.h"
|
|
15
|
+
#import "TscCommand.h"
|
|
16
|
+
#import "ImageTranster.h"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Seven365Zyprinter {
|
|
2
|
+
header "sources/POSSDK.h"
|
|
3
|
+
header "sources/POSBLEManager.h"
|
|
4
|
+
header "sources/POSWIFIManager.h"
|
|
5
|
+
header "sources/PosCommand.h"
|
|
6
|
+
header "sources/TscCommand.h"
|
|
7
|
+
header "sources/ImageTranster.h"
|
|
8
|
+
|
|
9
|
+
export *
|
|
10
|
+
module * { export * }
|
|
11
|
+
}
|
|
12
|
+
|