Skip to content

Commit

Permalink
Cache the previous stable time
Browse files Browse the repository at this point in the history
  • Loading branch information
mallorypaine committed Sep 18, 2017
1 parent 77cdbc5 commit 8f038ac
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
23 changes: 21 additions & 2 deletions Sources/Clock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,16 @@ import Foundation
/// ```
public struct Clock {

private static var stableTime: TimeFreeze?
private static let kDefaultsKey = "KronosStableTime"

private static var stableTime: TimeFreeze? {
didSet {
guard let stableTime = self.stableTime else {
return
}
UserDefaults.standard.set(stableTime.toDictionary(), forKey: kDefaultsKey)
}
}

/// The most accurate timestamp that we have so far (nil if no synchronization was done yet)
public static var timestamp: TimeInterval? {
Expand All @@ -42,7 +51,7 @@ public struct Clock {
first: ((Date, TimeInterval) -> Void)? = nil,
completion: ((Date?, TimeInterval?) -> Void)? = nil)
{
self.reset()
self.loadFromDefaults()

NTPClient().query(pool: pool, numberOfSamples: samples) { offset, done, total in
if let offset = offset {
Expand All @@ -64,4 +73,14 @@ public struct Clock {
public static func reset() {
self.stableTime = nil
}

private static func loadFromDefaults() {
guard let stored = UserDefaults.standard.value(forKey: kDefaultsKey) as? [String: TimeInterval],
let previousStableTime = TimeFreeze(from: stored) else
{
self.stableTime = nil
return
}
self.stableTime = previousStableTime
}
}
33 changes: 33 additions & 0 deletions Sources/TimeFreeze.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import Foundation

private let kUptimeKey = "Uptime"
private let kTimestampKey = "Timestamp"
private let kOffsetKey = "Offset"

struct TimeFreeze {
private let uptime: TimeInterval
private let timestamp: TimeInterval
Expand All @@ -22,6 +26,35 @@ struct TimeFreeze {
self.uptime = TimeFreeze.systemUptime()
}

init?(from dictionary: [String: TimeInterval]) {
guard let uptime = dictionary[kUptimeKey], let timestamp = dictionary[kTimestampKey],
let offset = dictionary[kOffsetKey] else
{
return nil
}

let currentBoot = TimeFreeze.systemUptime() - currentTime()
let previousBoot = uptime - timestamp
if rint(currentBoot) - rint(previousBoot) != 0 {
return nil
}

self.uptime = uptime
self.timestamp = timestamp
self.offset = offset
}

/// Convert this TimeFreeze to a dictionary representation.
///
/// - returns: A dictionary representation.
func toDictionary() -> [String: TimeInterval] {
return [
kUptimeKey: self.uptime,
kTimestampKey: self.timestamp,
kOffsetKey: self.offset,
]
}

/// Returns a high-resolution measurement of system uptime, that continues ticking through device sleep
/// *and* user- or system-generated clock adjustments. This allows for stable differences to be calculated
/// between timestamps.
Expand Down

0 comments on commit 8f038ac

Please sign in to comment.