@nitra/zebra 7.1.2 → 7.1.4
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.
|
@@ -87,6 +87,13 @@ import ExternalAccessory
|
|
|
87
87
|
private weak var owner: Zebra?
|
|
88
88
|
private var startTime = Date()
|
|
89
89
|
private let session: EASession
|
|
90
|
+
/// Чи отримано openCompleted на output; перший запис — лише після готовності сесії (див. readyToWrite).
|
|
91
|
+
private var outputOpenCompleted = false
|
|
92
|
+
/// Чи отримано openCompleted на input (якщо є). Події InputStream: openCompleted, hasBytesAvailable, errorOccurred, endEncountered.
|
|
93
|
+
/// Використовуємо input.openCompleted як сигнал "з'єднання з обох боків відкрите", щоб не покладатися на фіксовані таймаути.
|
|
94
|
+
private var inputOpenCompleted = false
|
|
95
|
+
/// Якщо inputStream відсутній, після output.openCompleted чекаємо цю затримку перед першим записом.
|
|
96
|
+
private static let delayAfterOpenWhenNoInput: TimeInterval = 0.35
|
|
90
97
|
|
|
91
98
|
init(owner: Zebra, session: EASession, output: OutputStream, data: [UInt8], address: String, timeout: TimeInterval = 5.0, completion: @escaping (Result<PrintResult, ZebraError>) -> Void) {
|
|
92
99
|
self.owner = owner
|
|
@@ -156,19 +163,56 @@ import ExternalAccessory
|
|
|
156
163
|
owner?.log("StreamWriter finished with", result)
|
|
157
164
|
}
|
|
158
165
|
|
|
166
|
+
/// Сесія готова до запису: output відкрито і (якщо є input) input теж відкрито — уникаємо фіксованих таймаутів.
|
|
167
|
+
private var readyToWrite: Bool {
|
|
168
|
+
guard outputOpenCompleted else { return false }
|
|
169
|
+
guard let input = session.inputStream else {
|
|
170
|
+
return true
|
|
171
|
+
}
|
|
172
|
+
return inputOpenCompleted
|
|
173
|
+
}
|
|
174
|
+
|
|
159
175
|
func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
|
|
160
|
-
// Події input
|
|
161
|
-
|
|
176
|
+
// Події input-потоку: openCompleted, hasBytesAvailable, errorOccurred, endEncountered (для читання відповідей принтера, якщо протокол підтримує)
|
|
177
|
+
if aStream !== output {
|
|
178
|
+
switch eventCode {
|
|
179
|
+
case .openCompleted:
|
|
180
|
+
owner?.log("Input stream open completed")
|
|
181
|
+
inputOpenCompleted = true
|
|
182
|
+
case .hasBytesAvailable:
|
|
183
|
+
// Можна читати input.read() для відповідей принтера — зараз не використовуємо
|
|
184
|
+
break
|
|
185
|
+
case .errorOccurred:
|
|
186
|
+
let reason = aStream.streamError?.localizedDescription ?? "Невідома помилка"
|
|
187
|
+
owner?.log("Input stream error:", reason)
|
|
188
|
+
case .endEncountered:
|
|
189
|
+
owner?.log("Input stream end encountered")
|
|
190
|
+
default:
|
|
191
|
+
break
|
|
192
|
+
}
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
|
|
162
196
|
if Date().timeIntervalSince(startTime) > timeout {
|
|
163
197
|
owner?.log("StreamWriter timeout")
|
|
164
198
|
close(with: .failure(.writeFailed("Таймаут запису")))
|
|
165
199
|
return
|
|
166
200
|
}
|
|
201
|
+
|
|
167
202
|
switch eventCode {
|
|
168
203
|
case .openCompleted:
|
|
169
|
-
|
|
170
|
-
|
|
204
|
+
owner?.log("Output stream open completed")
|
|
205
|
+
outputOpenCompleted = true
|
|
171
206
|
case .hasSpaceAvailable:
|
|
207
|
+
guard readyToWrite else { return }
|
|
208
|
+
// Якщо input потоку немає — після output.openCompleted все одно даємо коротку затримку (fallback)
|
|
209
|
+
if totalWritten == 0, session.inputStream == nil {
|
|
210
|
+
let deadline = Date().addingTimeInterval(StreamWriter.delayAfterOpenWhenNoInput)
|
|
211
|
+
while Date() < deadline {
|
|
212
|
+
RunLoop.current.run(mode: .default, before: Date().addingTimeInterval(0.05))
|
|
213
|
+
}
|
|
214
|
+
owner?.log("Delay after open (no input stream), starting write")
|
|
215
|
+
}
|
|
172
216
|
// Є простір для запису, пишемо дані порціями
|
|
173
217
|
if totalWritten >= data.count {
|
|
174
218
|
// Усі байти записані — даємо час на флаш буфера перед закриттям (iOS часто не встигає відправити на пристрій)
|