diff --git a/Sources/Clickstream/NetworkManager/Infrastructure/Utilities/DispatchSourceTimer+RepeatingTimer.swift b/Sources/Clickstream/NetworkManager/Infrastructure/Utilities/DispatchSourceTimer+RepeatingTimer.swift index e91caf3..5e249c6 100644 --- a/Sources/Clickstream/NetworkManager/Infrastructure/Utilities/DispatchSourceTimer+RepeatingTimer.swift +++ b/Sources/Clickstream/NetworkManager/Infrastructure/Utilities/DispatchSourceTimer+RepeatingTimer.swift @@ -15,7 +15,8 @@ import Foundation class RepeatingTimer { static let shared = RepeatingTimer() - var timeInterval: TimeInterval = 0 + private var timeInterval: TimeInterval = 0 + private var newTimer: DispatchSourceTimer? private init() { } @@ -23,6 +24,20 @@ class RepeatingTimer { self.timeInterval = timeInterval } + func setup(timeInterval: TimeInterval) { + self.timeInterval = timeInterval + setupTimer() + } + + private func setupTimer() { + guard timeInterval > 0 else { return } + newTimer = DispatchSource.makeTimerSource() + newTimer?.schedule(deadline: .now() + timeInterval, repeating: timeInterval) + newTimer?.setEventHandler { [weak self] in + self?.eventHandler?() + } + } + private lazy var timer: DispatchSourceTimer = { [weak self] in let t = DispatchSource.makeTimerSource() guard let checkedSelf = self else { return t } @@ -44,8 +59,13 @@ class RepeatingTimer { private var state: Atomic = Clickstream.timerCrashFixFlag ? Atomic(.notInitialized) : Atomic(.suspended) deinit { - timer.setEventHandler {} - timer.cancel() + if Clickstream.timerCrashFixFlag { + newTimer?.setEventHandler {} + newTimer?.cancel() + } else { + timer.setEventHandler {} + timer.cancel() + } /* If the timer is suspended, calling cancel without resuming triggers a crash. This is documented here https://forums.developer.apple.com/thread/15902 @@ -68,7 +88,11 @@ class RepeatingTimer { state.mutate { state in state = .resumed } - timer.resume() + if Clickstream.timerCrashFixFlag { + newTimer?.resume() + } else { + timer.resume() + } } func suspend() { @@ -78,6 +102,11 @@ class RepeatingTimer { state.mutate { state in state = .suspended } - timer.suspend() + + if Clickstream.timerCrashFixFlag { + newTimer?.suspend() + } else { + timer.suspend() + } } } diff --git a/Sources/Clickstream/NetworkManager/Infrastructure/Utilities/KeepAliveService.swift b/Sources/Clickstream/NetworkManager/Infrastructure/Utilities/KeepAliveService.swift index 26a12a3..cd81cc7 100644 --- a/Sources/Clickstream/NetworkManager/Infrastructure/Utilities/KeepAliveService.swift +++ b/Sources/Clickstream/NetworkManager/Infrastructure/Utilities/KeepAliveService.swift @@ -50,9 +50,9 @@ final class DefaultKeepAliveServiceWithSafeTimer: KeepAliveService { @discardableResult private func makeTimer() -> RepeatingTimer? { if Clickstream.timerCrashFixFlag { - let timerDuration = duration*reachability.connectionRetryCoefficient - RepeatingTimer.shared.timeInterval = timerDuration self.timer = RepeatingTimer.shared + let timerDuration = duration*reachability.connectionRetryCoefficient + timer?.setup(timeInterval: timerDuration) timer?.eventHandler = { [weak self] in guard let checkedSelf = self else { return } checkedSelf.performQueue.async {