Skip to content

Commit e4f81cc

Browse files
author
Marc-Antoine Sauvé
committed
Add the ability to specify RunLoop and RunLoopMode in after and
`every` methods while conserving the initial signature and behavior for backward compatibility
1 parent 77325e6 commit e4f81cc

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

Sources/SwiftyTimer.swift

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,28 +31,28 @@ extension Timer {
3131
/// Create and schedule a timer that will call `block` once after the specified time.
3232

3333
@discardableResult
34-
public class func after(_ interval: TimeInterval, _ block: @escaping () -> Void) -> Timer {
34+
public class func after(_ interval: TimeInterval, runLoop: RunLoop = .current, modes: RunLoopMode..., _ block: @escaping () -> Void) -> Timer {
3535
let timer = Timer.new(after: interval, block)
36-
timer.start()
36+
timer.start(runLoop: runLoop, modes: modes)
3737
return timer
3838
}
3939

4040
/// Create and schedule a timer that will call `block` repeatedly in specified time intervals.
4141

4242
@discardableResult
43-
public class func every(_ interval: TimeInterval, _ block: @escaping () -> Void) -> Timer {
43+
public class func every(_ interval: TimeInterval, runLoop: RunLoop = .current, modes: RunLoopMode..., _ block: @escaping () -> Void) -> Timer {
4444
let timer = Timer.new(every: interval, block)
45-
timer.start()
45+
timer.start(runLoop: runLoop, modes: modes)
4646
return timer
4747
}
4848

4949
/// Create and schedule a timer that will call `block` repeatedly in specified time intervals.
5050
/// (This variant also passes the timer instance to the block)
5151

5252
@nonobjc @discardableResult
53-
public class func every(_ interval: TimeInterval, _ block: @escaping (Timer) -> Void) -> Timer {
53+
public class func every(_ interval: TimeInterval, runLoop: RunLoop = .current, modes: RunLoopMode..., _ block: @escaping (Timer) -> Void) -> Timer {
5454
let timer = Timer.new(every: interval, block)
55-
timer.start()
55+
timer.start(runLoop: runLoop, modes: modes)
5656
return timer
5757
}
5858

@@ -111,6 +111,20 @@ extension Timer {
111111
runLoop.add(self, forMode: mode)
112112
}
113113
}
114+
115+
/// Schedule this timer on the run loop
116+
///
117+
/// By default, the timer is scheduled on the current run loop for the default mode.
118+
/// Specify `runLoop` or `modes` to override these defaults.
119+
/// Usefull since the splat operator is not a thing in Swift
120+
121+
public func start(runLoop: RunLoop = .current, modes: [RunLoopMode]) {
122+
let modes = modes.isEmpty ? [.defaultRunLoopMode] : modes
123+
124+
for mode in modes {
125+
runLoop.add(self, forMode: mode)
126+
}
127+
}
114128
}
115129

116130
// MARK: - Time extensions

SwiftyTimerTests/SwiftyTimerTests/main.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,19 @@ class AppDelegate: NSObject, NSApplicationDelegate {
101101
guard fires <= 1 else { fatalError("should be invalidated") }
102102
defer { fires += 1 }
103103

104+
if fires == 1 {
105+
timer.invalidate()
106+
self.test10()
107+
}
108+
}
109+
}
110+
111+
func test10() {
112+
var fires = 0
113+
Timer.every(0.1.seconds, modes: .commonModes) { (timer: Timer) in
114+
guard fires <= 1 else { fatalError("should be invalidated") }
115+
defer { fires += 1 }
116+
104117
if fires == 1 {
105118
timer.invalidate()
106119
self.done()

0 commit comments

Comments
 (0)