ielyamani
ielyamani

Reputation: 18581

Throttling in Swift without going reactive

Is there a simple way of implementing the Throttle feature in Reactive programming without having to use RxSwift or similar frameworks.

I have a textField delegate method that I would like not to fire every time a character is inserted/deleted.

How to do that using vanilla Foundation?

Upvotes: 4

Views: 9877

Answers (2)

boraseoksoon
boraseoksoon

Reputation: 2445

  • disclaimer: I am a writer.

Throttler can be the right katana to make you happy.

You can do debounce and throttle without going reactive programming using Throttler like,

import Throttler

// advanced debounce, running a first task immediately before initiating debounce.

for i in 1...1000 {
    Throttler.debounce {
        print("debounce! > \(i)")
    }
}

// debounce! > 1
// debounce! > 1000


// equivalent to debounce of Combine, RxSwift.

for i in 1...1000 {
    Throttler.debounce(shouldRunImmediately: false) {
        print("debounce! > \(i)")
    }
}

// debounce! > 1000

Throttler also can do advanced debounce, running a first event immediately before initiating debounce that Combine and RxSwift don't have by default.

You could, but you may need a complex implementation yourself for that.

Upvotes: 2

Oleg Gordiichuk
Oleg Gordiichuk

Reputation: 15512

Yes it is possible to achieve.

But first lets answer small question what is Throttling?

In software, a throttling process, or a throttling controller as it is sometimes called, is a process responsible for regulating the rate at which application processing is conducted, either statically or dynamically.

Example of the Throttling function in the Swift.

In case that you have describe with delegate method you will have issue that delegate method will be called each time. So I will write short example how it impossible to do in the case you describe.

class ViewController: UIViewController {
    
    var timer: Timer?
    
    @IBOutlet weak var textField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = self
    }
    
    @objc func validate() {
        print("Validate is called")
    }
}

extension ViewController: UITextFieldDelegate {
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        
        timer?.invalidate()
        
        timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(self.validate), userInfo: nil, repeats: false);
        
        return true
    }

}

Upvotes: 11

Related Questions