Skip to content

Commit

Permalink
Simplify and fix countdown display skipping seconds (#94)
Browse files Browse the repository at this point in the history
- Simplify the tick timer code by using round() instead of floor() to handle the variance in exact fire times
- Bump version to 1.5.5

Co-authored-by: Ali Karbassi <ali@karbassi.com>
  • Loading branch information
robinstewart and karbassi committed Jul 16, 2020
1 parent d06658d commit a5063ef
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 25 deletions.
4 changes: 2 additions & 2 deletions Timer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@
INFOPLIST_FILE = Timer/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
MARKETING_VERSION = 1.5.4;
MARKETING_VERSION = 1.5.5;
PRODUCT_BUNDLE_IDENTIFIER = com.michaelvillar.Timer;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
Expand All @@ -319,7 +319,7 @@
INFOPLIST_FILE = Timer/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
MARKETING_VERSION = 1.5.4;
MARKETING_VERSION = 1.5.5;
PRODUCT_BUNDLE_IDENTIFIER = com.michaelvillar.Timer;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
Expand Down
39 changes: 16 additions & 23 deletions Timer/MVClockView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -408,15 +408,19 @@ class MVClockView: NSControl {
self.paused = false
self.stop()

// Ensure that each countdown tick occurs just past the exact seconds boundary
// (so system delays won't affect the value displayed)
self.timer = Timer.scheduledTimer(
timeInterval: 0.97,
// Since the UI only allows timers to be set in multiples of 1 second, each tick
// will fire _near_ an integer seconds-remaining boundary.
self.timer = Foundation.Timer.scheduledTimer(
timeInterval: 1, // (second)
target: self,
selector: #selector(firstTick),
selector: #selector(tick),
userInfo: nil,
repeats: false
repeats: true
)

// Improves the system's ability to optimize for increased power savings by allowing
// the timer a small amount of variance in when it can fire (without drifting over time).
self.timer?.tolerance = 0.03 // (seconds)
}

func stop() {
Expand All @@ -428,26 +432,15 @@ class MVClockView: NSControl {
}
}

@objc func firstTick() {
self.tick()
self.timer = Foundation.Timer.scheduledTimer(
timeInterval: 1,
target: self,
selector: #selector(tick),
userInfo: nil,
repeats: true
)

// Improves the system's ability to optimize for increased power savings and responsiveness
// A general rule, set the tolerance to at least 10% of the interval, for a repeating timer.
currentTimeTimer?.tolerance = 0.03
}

@objc func tick() {
guard let timerTime = self.timerTime else { return }

self.seconds = fmax(0, floor(CGFloat(timerTime.timeIntervalSinceNow)))
if self.seconds <= 0 {
let secondsRemaining = CGFloat(timerTime.timeIntervalSinceNow)

// Round the seconds displayed on the clock face
self.seconds = max(0, round(secondsRemaining))

if self.seconds <= 0 { // Timer is done!
self.stop()
_ = self.target?.perform(self.action, with: self)
}
Expand Down

0 comments on commit a5063ef

Please sign in to comment.