diff --git a/Tarnax/App.swift b/Tarnax/App.swift
index fb07c4f..e47c2aa 100644
--- a/Tarnax/App.swift
+++ b/Tarnax/App.swift
@@ -287,7 +287,7 @@ struct TransferHistoryChart: View {
private var end: Date { updatedAt ?? Date() }
private var start: Date { end.addingTimeInterval(-Double(minutes * 60)) }
- private var samples: [TransferSample] { history.samples.filter { $0.date >= start && $0.date <= end } }
+ private var samples: [TransferSample] { history.samples(from: start, through: end) }
private var selectedSample: TransferSample? {
guard let selection else { return nil }
return samples.min { abs($0.date.timeIntervalSince(selection)) < abs($1.date.timeIntervalSince(selection)) }
diff --git a/Tarnax/Core.swift b/Tarnax/Core.swift
index c947621..bd243fc 100644
--- a/Tarnax/Core.swift
+++ b/Tarnax/Core.swift
@@ -140,9 +140,19 @@ struct TransferHistory {
private(set) var samples: [TransferSample] = []
private var segment = 0
+ func samples(from start: Date, through end: Date) -> [TransferSample] {
+ let lower = start.timeIntervalSinceReferenceDate
+ let upper = end.timeIntervalSinceReferenceDate
+ // Avoid SDK-new Date >= / <= entry points missing from some iOS betas.
+ return samples.filter {
+ let time = $0.date.timeIntervalSinceReferenceDate
+ return time >= lower && time <= upper
+ }
+ }
+
mutating func record(download: Int64, upload: Int64, at date: Date = Date()) {
if let last = samples.last {
- guard date >= last.date else { return }
+ guard date.timeIntervalSinceReferenceDate >= last.date.timeIntervalSinceReferenceDate else { return }
if date.timeIntervalSince(last.date) > 10 { segment += 1 }
// Extra action/manual refreshes must not inflate the history buffer.
if date.timeIntervalSince(last.date) < 1 { samples.removeLast() }
diff --git a/Tarnax/Info.plist b/Tarnax/Info.plist
index 09f9039..3578bac 100644
--- a/Tarnax/Info.plist
+++ b/Tarnax/Info.plist
@@ -15,7 +15,7 @@
CFBundleShortVersionString
1.0
CFBundleVersion
- 5
+ 6
LSRequiresIPhoneOS
NSFaceIDUsageDescription
diff --git a/Tests/ContractTests.swift b/Tests/ContractTests.swift
index cd0fc51..2a769f5 100644
--- a/Tests/ContractTests.swift
+++ b/Tests/ContractTests.swift
@@ -249,6 +249,10 @@ final class MockProtocol: URLProtocol, @unchecked Sendable {
check(liveHistory.transferHistory.samples.count == 1, "Failed refresh never fabricates a speed sample")
liveHistory.disconnect()
check(liveHistory.transferHistory.samples.isEmpty, "Disconnect removes actual collected history")
+ var windowHistory = TransferHistory()
+ for second in [0, 3, 6] { windowHistory.record(download: 1, upload: 2, at: origin.addingTimeInterval(Double(second))) }
+ check(windowHistory.samples(from: origin.addingTimeInterval(3), through: origin.addingTimeInterval(6)).count == 2, "History window includes exact timestamp boundaries without new Date comparison entry points")
+ check(windowHistory.samples(from: origin.addingTimeInterval(7), through: origin.addingTimeInterval(9)).isEmpty, "History window excludes samples outside its numeric time range")
another.close(); transport.close(); print("\(checks) contract checks passed.")
}
}