Created
June 28, 2018 11:49
-
-
Save srstanic/34ecbb32adbc5ac6612fb41f6b80e020 to your computer and use it in GitHub Desktop.
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 | |
| typealias VoidVoid = () -> () | |
| 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