Skip to content

Commit 0c3d8be

Browse files
authored
[Woo POS][Barcodes] Timeout a partial scan with no terminating character (#15952)
2 parents 737681a + 50872ac commit 0c3d8be

File tree

5 files changed

+253
-24
lines changed

5 files changed

+253
-24
lines changed

WooCommerce/Classes/POS/Models/Cart+BarcodeScanError.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ extension PointOfSaleBarcodeScanError {
121121
)
122122

123123
static let incompleteScan = NSLocalizedString(
124-
"pointOfSale.barcodeScan.error.incompleteScan",
125-
value: "Partial barcode scan",
126-
comment: "Error message shown when scan is incomplete."
124+
"pointOfSale.barcodeScan.error.incompleteScan.2",
125+
value: "The scanner did not send an end-of-line character",
126+
comment: "Error message shown when scanner times out without sending end-of-line character."
127127
)
128128

129129
static let parsingError = NSLocalizedString(

WooCommerce/Classes/POS/Presentation/Barcode Scanning/GameControllerBarcodeParser.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ final class GameControllerBarcodeParser {
1515
private var buffer = ""
1616
private var lastKeyPressTime: Date?
1717
private var scanStartTime: Date?
18+
private var timeoutTimer: Timer?
1819

1920
init(configuration: HIDBarcodeParserConfiguration,
2021
onScan: @escaping (HIDBarcodeParserResult) -> Void,
@@ -49,6 +50,7 @@ final class GameControllerBarcodeParser {
4950
}
5051

5152
buffer.append(character)
53+
scheduleTimeoutTimer()
5254
}
5355
}
5456

@@ -186,6 +188,31 @@ final class GameControllerBarcodeParser {
186188
buffer = ""
187189
lastKeyPressTime = nil
188190
scanStartTime = nil
191+
cancelTimeoutTimer()
192+
}
193+
194+
private func scheduleTimeoutTimer() {
195+
cancelTimeoutTimer()
196+
timeoutTimer = timeProvider.scheduleTimer(
197+
timeInterval: configuration.maximumInterCharacterTime,
198+
target: self,
199+
selector: #selector(handleTimeoutExpiry)
200+
)
201+
}
202+
203+
private func cancelTimeoutTimer() {
204+
timeoutTimer?.invalidate()
205+
timeoutTimer = nil
206+
}
207+
208+
@objc private func handleTimeoutExpiry() {
209+
guard !buffer.isEmpty else { return }
210+
211+
let scanDurationMs = calculateScanDurationMs()
212+
let result = HIDBarcodeParserResult.failure(error: HIDBarcodeParserError.timedOut(barcode: buffer), scanDurationMs: scanDurationMs)
213+
214+
onScan(result)
215+
resetScan()
189216
}
190217

191218
private func calculateScanDurationMs() -> Int {
@@ -194,6 +221,7 @@ final class GameControllerBarcodeParser {
194221
}
195222

196223
private func processScan() {
224+
cancelTimeoutTimer()
197225
checkForTimeoutBetweenKeystrokes()
198226
let scanDurationMs = calculateScanDurationMs()
199227

WooCommerce/Classes/POS/Presentation/Barcode Scanning/TimeProvider.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@ import Foundation
22

33
protocol TimeProvider {
44
func now() -> Date
5+
func scheduleTimer(timeInterval: TimeInterval, target: Any, selector: Selector) -> Timer
56
}
67

78
struct DefaultTimeProvider: TimeProvider {
89
func now() -> Date {
910
Date()
1011
}
12+
13+
func scheduleTimer(timeInterval: TimeInterval, target: Any, selector: Selector) -> Timer {
14+
return Timer.scheduledTimer(timeInterval: timeInterval, target: target, selector: selector, userInfo: nil, repeats: false)
15+
}
1116
}

0 commit comments

Comments
 (0)