Files
2017-08-29 11:29:55 +01:00

72 lines
2.2 KiB
Swift
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// NetworkSpeedTracker.swift
// BitTorrent
//
// Created by Ben Davis on 13/08/2017.
// Copyright © 2017 Ben Davis. All rights reserved.
//
import Foundation
public protocol NetworkSpeedTrackable {
var totalNumberOfBytes: Int { get }
func numberOfBytesDownloaded(since date: Date) -> Int
func numberOfBytesDownloaded(over timeInterval: TimeInterval) -> Int
}
public struct NetworkSpeedTracker: NetworkSpeedTrackable {
public var totalNumberOfBytes: Int = 0
// TODO: limit number of dataPoints stored
private var dataPoints: [NetworkSpeedDataPoint] = [NetworkSpeedDataPoint(0)]
mutating func increase(by bytes: Int) {
totalNumberOfBytes += bytes
addDataPoint(NetworkSpeedDataPoint(totalNumberOfBytes))
}
private mutating func addDataPoint(_ dataPoint: NetworkSpeedDataPoint) {
dataPoints = [dataPoint] + dataPoints
}
public func numberOfBytesDownloaded(since date: Date) -> Int {
guard let previouslyDataPoint = dataPoints.firstWhere({ $0.dateRecorded < date }) else {
return totalNumberOfBytes
}
return totalNumberOfBytes - previouslyDataPoint.numberOfBytes
}
public func numberOfBytesDownloaded(over timeInterval: TimeInterval) -> Int {
return numberOfBytesDownloaded(since: Date(timeIntervalSinceNow: -timeInterval))
}
}
public struct NetworkSpeedDataPoint: Equatable, Comparable {
var numberOfBytes: Int
var dateRecorded: Date
init(_ numberOfBytes: Int, dateRecorded: Date = Date()) {
self.numberOfBytes = numberOfBytes
self.dateRecorded = dateRecorded
}
public static func ==(_ lhs: NetworkSpeedDataPoint, _ rhs: NetworkSpeedDataPoint) -> Bool {
return (
lhs.numberOfBytes == rhs.numberOfBytes &&
lhs.dateRecorded == rhs.dateRecorded
)
}
public static func <(lhs: NetworkSpeedDataPoint, rhs: NetworkSpeedDataPoint) -> Bool {
return lhs.dateRecorded.compare(rhs.dateRecorded) == .orderedAscending
}
}
// Not sure why I need this 🤷
extension Collection {
func firstWhere(_ predicate: (Element) -> Bool) -> Element? {
return first(where: predicate)
}
}