Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 57 additions & 44 deletions Sources/SwiftTimer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,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) {


public init(
interval: DispatchTimeInterval,
repeats: Bool = false,
queue: DispatchQueue = .main,
handler: @escaping SwiftTimerHandler) {

self.handler = handler
self.repeats = repeats
internalTimer = DispatchSource.makeTimerSource(queue: queue)
Expand All @@ -30,25 +34,29 @@ public class SwiftTimer {
handler(strongSelf)
}
}

if repeats {
internalTimer.scheduleRepeating(deadline: .now() + interval, interval: interval)
} else {
internalTimer.scheduleOneshot(deadline: .now() + interval)
}
}

public static func repeaticTimer(interval: DispatchTimeInterval, queue: DispatchQueue = .main , handler: @escaping SwiftTimerHandler ) -> SwiftTimer {

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.

// 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)
Expand All @@ -57,27 +65,27 @@ public class SwiftTimer {
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.scheduleRepeating(deadline: .now() + interval, interval: interval)
}
}

public func rescheduleHandler(handler: @escaping SwiftTimerHandler) {
self.handler = handler
internalTimer.setEventHandler { [weak self] in
Expand All @@ -89,18 +97,22 @@ public class SwiftTimer {
}
}

//MARK: Throttle
// 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 ) {


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.scheduleOneshot(deadline: .now() + interval)
Expand All @@ -111,64 +123,65 @@ public extension SwiftTimer {
}
timer.resume()
}

public static func cancelThrottlingTimer(identifier: String) {
if let previousTimer = timers[identifier] {
previousTimer.cancel()
timers.removeValue(forKey: identifier)
}
}



}

//MARK: Count Down
// 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 ) {


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
self.internalTimer.rescheduleHandler { [weak self] _ in
if let strongSelf = self {
if strongSelf.leftTimes > 0 {
strongSelf.leftTimes = strongSelf.leftTimes - 1
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))
}
Expand Down
47 changes: 44 additions & 3 deletions SwiftTimer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0800;
LastUpgradeCheck = 0800;
LastUpgradeCheck = 0830;
TargetAttributes = {
BF84D1681D6C016500B5B511 = {
CreatedOnToolsVersion = 8.0;
Expand Down Expand Up @@ -404,12 +404,48 @@
BF84D1621D6C010700B5B511 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
};
name = Debug;
};
BF84D1631D6C010700B5B511 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
};
name = Release;
};
Expand All @@ -435,7 +471,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
Expand Down Expand Up @@ -500,7 +536,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
Expand Down Expand Up @@ -1024,6 +1060,7 @@
BF84D1711D6C016500B5B511 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
BF84D17C1D6C01A600B5B511 /* Build configuration list for PBXNativeTarget "SwiftTimer watchOS" */ = {
isa = XCConfigurationList;
Expand All @@ -1032,6 +1069,7 @@
BF84D17E1D6C01A600B5B511 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
BF84D1891D6C01C000B5B511 /* Build configuration list for PBXNativeTarget "SwiftTimer tvOS" */ = {
isa = XCConfigurationList;
Expand All @@ -1040,6 +1078,7 @@
BF84D18B1D6C01C000B5B511 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
BF84D1961D6C01DD00B5B511 /* Build configuration list for PBXNativeTarget "SwiftTimer macOS" */ = {
isa = XCConfigurationList;
Expand All @@ -1048,6 +1087,7 @@
BF84D1981D6C01DD00B5B511 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
BF84D1C51D6C0F1600B5B511 /* Build configuration list for PBXNativeTarget "SwiftTimer iOSTests" */ = {
isa = XCConfigurationList;
Expand All @@ -1056,6 +1096,7 @@
BF84D1C71D6C0F1600B5B511 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
LastUpgradeVersion = "0830"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
LastUpgradeVersion = "0830"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
LastUpgradeVersion = "0830"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down