Skip to content

Instantly share code, notes, and snippets.

@srstanic
Created December 2, 2018 11:02
Show Gist options
  • Select an option

  • Save srstanic/59a62031a9ba42cb84ed73c5ee68cdd6 to your computer and use it in GitHub Desktop.

Select an option

Save srstanic/59a62031a9ba42cb84ed73c5ee68cdd6 to your computer and use it in GitHub Desktop.
Repeating blocks
import Foundation
protocol Repeating {
func startRepeating(withIntervalInSeconds: TimeInterval)
func stopRepeating()
}
/// Doesn't wait for the block to finish
class ImpatientRepeater: Repeating {
required init(withBlock block: @escaping VoidVoid) {
self.block = block
}
private let block: VoidVoid
func startRepeating(withIntervalInSeconds timeInterval: TimeInterval) {
self.stopRepeating()
self.executeBlock()
self.timer = Timer.scheduledTimer(timeInterval: timeInterval,
target: self,
selector: #selector(self.executeBlock),
userInfo: nil,
repeats: true)
}
@objc func executeBlock() {
self.block()
}
func stopRepeating() {
if timer != nil {
timer?.invalidate()
timer = nil
}
}
private var timer: Timer?
}
/// Waits for the block to finish
class PatientRepeater: Repeating {
/// Block argument is a closure that accepts a completion handler as an argument,
/// calls it once it is done and passes true if it wants to be called again after
/// the defined time interval (usually that's when the block was successful) or
/// false if it wants to be called again immediatelly (usually when the block failed).
required init(withBlock block: @escaping (@escaping (Bool) -> Void) -> Void) {
self.block = block
}
private let block: (@escaping (Bool) -> Void) -> Void
private let defaultTimeInterval: TimeInterval = 10
func startRepeating(withIntervalInSeconds timeInterval: TimeInterval) {
stopRepeating()
self.timeInterval = timeInterval
isRepeating = true
executeBlock()
}
@objc func executeBlock() {
self.block { shouldWaitToRepeat in
if shouldWaitToRepeat {
if self.isRepeating {
self.timer = Timer.scheduledTimer(timeInterval: self.timeInterval ?? self.defaultTimeInterval,
target: self,
selector: #selector(self.executeBlock),
userInfo: nil,
repeats: false)
}
} else {
self.executeBlock()
}
}
}
func stopRepeating() {
isRepeating = false
timer?.invalidate()
}
private var isRepeating: Bool = false
private var timeInterval: TimeInterval?
private var timer: Timer?
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment