Created
December 2, 2018 11:02
-
-
Save srstanic/59a62031a9ba42cb84ed73c5ee68cdd6 to your computer and use it in GitHub Desktop.
Repeating blocks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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