Skip to content

Instantly share code, notes, and snippets.

@Pircate
Last active February 28, 2019 12:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Pircate/faaf567504bb823da875a9982b2fd0be to your computer and use it in GitHub Desktop.
Save Pircate/faaf567504bb823da875a9982b2fd0be to your computer and use it in GitHub Desktop.
#import "NSNumber+Countdown.h"
@implementation NSNumber (Countdown)
- (dispatch_source_t)countdownWithInterval:(NSTimeInterval)interval
executing:(void (^)(NSTimeInterval))executing
completion:(void (^)(void))completion {
__block NSTimeInterval timeout = self.doubleValue;
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
timeout -= interval;
if (timeout < 1) {
dispatch_source_cancel(timer);
dispatch_async(dispatch_get_main_queue(), ^{
!completion ?: completion();
});
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
!executing ?: executing(timeout);
});
});
dispatch_resume(timer);
return timer;
}
@end
extension TimeInterval {
public func countdown(
repeating: TimeInterval = 1,
executing: @escaping (TimeInterval) -> Void,
completion: @escaping () -> Void)
-> DispatchSourceTimer
{
let timer = DispatchSource.makeTimerSource()
timer.schedule(wallDeadline: .now(), repeating: repeating)
var timeout = self
timer.setEventHandler {
timeout -= repeating
guard timeout >= 1 else {
timer.cancel()
DispatchQueue.main.async { completion() }
return
}
DispatchQueue.main.async { executing(timeout) }
}
timer.resume()
return timer
}
}
extension Int {
public func countdown(
repeating: TimeInterval = 1,
executing: @escaping (TimeInterval) -> Void,
completion: @escaping () -> Void)
-> DispatchSourceTimer
{
return TimeInterval(self).countdown(
repeating: repeating,
executing: executing,
completion: completion)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment