123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- //
- // SwiftTimer.swift
- // SwiftTimer
- //
- // Created by mangofang on 16/8/23.
- //
- //
- import Foundation
- public class SwiftTimer {
-
- private let internalTimer: DispatchSourceTimer
-
- private var isRunning = false
-
- public let repeats: Bool
-
- public typealias SwiftTimerHandler = (SwiftTimer) -> Void
-
- private var handler: SwiftTimerHandler
-
- public init(interval: DispatchTimeInterval, repeats: Bool = false, queue: DispatchQueue = .main , handler: @escaping SwiftTimerHandler) {
-
- self.handler = handler
- self.repeats = repeats
- internalTimer = DispatchSource.makeTimerSource(queue: queue)
- internalTimer.setEventHandler { [weak self] in
- if let strongSelf = self {
- handler(strongSelf)
- }
- }
-
- if repeats {
- internalTimer.schedule(deadline: .now() + interval, repeating: interval)
- } else {
- internalTimer.schedule(deadline: .now() + interval)
- }
- }
-
- public static func repeaticTimer(interval: DispatchTimeInterval, queue: DispatchQueue = .main , handler: @escaping SwiftTimerHandler ) -> SwiftTimer {
- return SwiftTimer(interval: interval, repeats: true, queue: queue, handler: handler)
- }
-
- deinit {
- if !self.isRunning {
- internalTimer.resume()
- }
- }
-
- //You can use this method to fire a repeating timer without interrupting its regular firing schedule. If the timer is non-repeating, it is automatically invalidated after firing, even if its scheduled fire date has not arrived.
- public func fire() {
- if repeats {
- handler(self)
- } else {
- handler(self)
- internalTimer.cancel()
- }
- }
-
- public func start() {
- if !isRunning {
- internalTimer.resume()
- isRunning = true
- }
- }
-
- public func suspend() {
- if isRunning {
- internalTimer.suspend()
- isRunning = false
- }
- }
-
- public func rescheduleRepeating(interval: DispatchTimeInterval) {
- if repeats {
- internalTimer.schedule(deadline: .now() + interval, repeating: interval)
- }
- }
-
- public func rescheduleHandler(handler: @escaping SwiftTimerHandler) {
- self.handler = handler
- internalTimer.setEventHandler { [weak self] in
- if let strongSelf = self {
- handler(strongSelf)
- }
- }
- }
- }
- //MARK: Throttle
- public extension SwiftTimer {
-
- private static var timers = [String:DispatchSourceTimer]()
-
- public static func throttle(interval: DispatchTimeInterval, identifier: String, queue: DispatchQueue = .main , handler: @escaping () -> Void ) {
-
- if let previousTimer = timers[identifier] {
- previousTimer.cancel()
- timers.removeValue(forKey: identifier)
- }
-
- let timer = DispatchSource.makeTimerSource(queue: queue)
- timers[identifier] = timer
- timer.schedule(deadline: .now() + interval)
- timer.setEventHandler {
- handler()
- timer.cancel()
- timers.removeValue(forKey: identifier)
- }
- timer.resume()
- }
-
- public static func cancelThrottlingTimer(identifier: String) {
- if let previousTimer = timers[identifier] {
- previousTimer.cancel()
- timers.removeValue(forKey: identifier)
- }
- }
-
-
-
- }
- //MARK: Count Down
- public class SwiftCountDownTimer {
-
- private let internalTimer: SwiftTimer
-
- private var leftTimes: Int
-
- private let originalTimes: Int
-
- private let handler: (SwiftCountDownTimer, _ leftTimes: Int) -> Void
-
- public init(interval: DispatchTimeInterval, times: Int,queue: DispatchQueue = .main , handler: @escaping (SwiftCountDownTimer, _ leftTimes: Int) -> Void ) {
-
- self.leftTimes = times
- self.originalTimes = times
- self.handler = handler
- self.internalTimer = SwiftTimer.repeaticTimer(interval: interval, queue: queue, handler: { _ in
- })
- self.internalTimer.rescheduleHandler { [weak self] swiftTimer in
- if let strongSelf = self {
- if strongSelf.leftTimes > 0 {
- strongSelf.leftTimes = strongSelf.leftTimes - 1
- strongSelf.handler(strongSelf, strongSelf.leftTimes)
- } else {
- strongSelf.internalTimer.suspend()
- }
- }
- }
- }
-
- public func start() {
- self.internalTimer.start()
- }
-
- public func suspend() {
- self.internalTimer.suspend()
- }
-
- public func reCountDown() {
- self.leftTimes = self.originalTimes
- }
-
- }
- public extension DispatchTimeInterval {
-
- public static func fromSeconds(_ seconds: Double) -> DispatchTimeInterval {
- return .milliseconds(Int(seconds * 1000))
- }
- }
|