I'm trying to find the best way to handle this. I'm currently looking to wait until user stops typing (let's say delay 3s) before running some code. Initially I was going to use textFieldDidEndEditing
but as we know this only executes when user returns, rather than when they stop typing.
Currently I use an @IBAction textFieldEditingChanged
but this will execute the code with each entered character/number. I tried to use a variable like shouldExecuteCode: Bool
but since I'm parsing an XML, the response is almost immediate and the code still get executed several times.
I was thinking to use some sort of OperationQueue
with one operation or no concurrency.
Anyone got a good idea for this?
Current Implementation
@IBAction func textFieldEditingChanged(_ sender: CurrencyTextField) {
self.viewModel.currentTextFieldIdentifier = sender.textFieldIdentifier
DispatchQueue.main.asyncAfter(deadline: .now() + viewModel.calculationDelay) {
if let text = sender.text,
let value = String.format(text) {
switch self.viewModel.currentTextFieldIdentifier {
case .fromCurrency:
self.calculateExchange(value: value,
valueCurrency: self.fromCurrencyTextField.currency,
outputCurrency: self.toCurrencyTextField.currency)
case .toCurrency:
self.calculateExchange(value: value,
valueCurrency: self.toCurrencyTextField.currency,
outputCurrency: self.fromCurrencyTextField.currency)
}
}
}
}
Potential Implementation
NotificationCenter.default
.publisher(for: UITextField.textDidChangeNotification, object: sender)
.map({ ($0.object as? UITextField)?.text ?? "" })
.debounce(for: .milliseconds(500), scheduler: RunLoop.main)
.sink { [weak self] text in
guard let self = self else { return }
if let value = String.format(text) {
print(value)
switch self.viewModel.currencyTextFieldIdentifier {
case .fromCurrency:
self.calculateExchange(value: value,
valueCurrency: self.fromCurrencyTextField.currency,
outputCurrency: self.toCurrencyTextField.currency)
case .toCurrency:
self.calculateExchange(value: value,
valueCurrency: self.toCurrencyTextField.currency,
outputCurrency: self.fromCurrencyTextField.currency)
}
}
}
.store(in: &subscriptions)