Refactor globals
This commit is contained in:
parent
ab64dac7fc
commit
f731927dcd
@ -28,10 +28,8 @@
|
|||||||
88CDE0632A253AD900114294 /* TemperatureDataTransfer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE0622A253AD900114294 /* TemperatureDataTransfer.swift */; };
|
88CDE0632A253AD900114294 /* TemperatureDataTransfer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE0622A253AD900114294 /* TemperatureDataTransfer.swift */; };
|
||||||
88CDE0662A25D08F00114294 /* SFSafeSymbols in Frameworks */ = {isa = PBXBuildFile; productRef = 88CDE0652A25D08F00114294 /* SFSafeSymbols */; };
|
88CDE0662A25D08F00114294 /* SFSafeSymbols in Frameworks */ = {isa = PBXBuildFile; productRef = 88CDE0652A25D08F00114294 /* SFSafeSymbols */; };
|
||||||
88CDE0682A2698B400114294 /* TemperatureStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE0672A2698B400114294 /* TemperatureStorage.swift */; };
|
88CDE0682A2698B400114294 /* TemperatureStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE0672A2698B400114294 /* TemperatureStorage.swift */; };
|
||||||
88CDE06B2A2899C900114294 /* BottomSheet in Frameworks */ = {isa = PBXBuildFile; productRef = 88CDE06A2A2899C900114294 /* BottomSheet */; };
|
|
||||||
88CDE06D2A28A92000114294 /* DeviceInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE06C2A28A92000114294 /* DeviceInfo.swift */; };
|
88CDE06D2A28A92000114294 /* DeviceInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE06C2A28A92000114294 /* DeviceInfo.swift */; };
|
||||||
88CDE0702A28AEA300114294 /* TemperatureMeasurement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE06F2A28AEA300114294 /* TemperatureMeasurement.swift */; };
|
88CDE0702A28AEA300114294 /* TemperatureMeasurement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE06F2A28AEA300114294 /* TemperatureMeasurement.swift */; };
|
||||||
88CDE0722A28AEB900114294 /* TemperatureDataTransferDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE0712A28AEB900114294 /* TemperatureDataTransferDelegate.swift */; };
|
|
||||||
88CDE0742A28AEE500114294 /* DeviceManagerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE0732A28AEE500114294 /* DeviceManagerDelegate.swift */; };
|
88CDE0742A28AEE500114294 /* DeviceManagerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE0732A28AEE500114294 /* DeviceManagerDelegate.swift */; };
|
||||||
88CDE0762A28AF0900114294 /* TemperatureValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE0752A28AF0900114294 /* TemperatureValue.swift */; };
|
88CDE0762A28AF0900114294 /* TemperatureValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE0752A28AF0900114294 /* TemperatureValue.swift */; };
|
||||||
88CDE0782A28AF2C00114294 /* TemperatureSensor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE0772A28AF2C00114294 /* TemperatureSensor.swift */; };
|
88CDE0782A28AF2C00114294 /* TemperatureSensor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE0772A28AF2C00114294 /* TemperatureSensor.swift */; };
|
||||||
@ -39,7 +37,6 @@
|
|||||||
88CDE07E2A28AFF400114294 /* DeviceInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE07D2A28AFF400114294 /* DeviceInfoView.swift */; };
|
88CDE07E2A28AFF400114294 /* DeviceInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CDE07D2A28AFF400114294 /* DeviceInfoView.swift */; };
|
||||||
E253A9222A2B39B700EC6B28 /* Color+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E253A9212A2B39B700EC6B28 /* Color+Extensions.swift */; };
|
E253A9222A2B39B700EC6B28 /* Color+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E253A9212A2B39B700EC6B28 /* Color+Extensions.swift */; };
|
||||||
E253A9242A2B462500EC6B28 /* TemperatureHistoryChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = E253A9232A2B462500EC6B28 /* TemperatureHistoryChart.swift */; };
|
E253A9242A2B462500EC6B28 /* TemperatureHistoryChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = E253A9232A2B462500EC6B28 /* TemperatureHistoryChart.swift */; };
|
||||||
E253A9272A2CA48A00EC6B28 /* SQLite in Frameworks */ = {isa = PBXBuildFile; productRef = E253A9262A2CA48A00EC6B28 /* SQLite */; };
|
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
@ -65,7 +62,6 @@
|
|||||||
88CDE0672A2698B400114294 /* TemperatureStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemperatureStorage.swift; sourceTree = "<group>"; };
|
88CDE0672A2698B400114294 /* TemperatureStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemperatureStorage.swift; sourceTree = "<group>"; };
|
||||||
88CDE06C2A28A92000114294 /* DeviceInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceInfo.swift; sourceTree = "<group>"; };
|
88CDE06C2A28A92000114294 /* DeviceInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceInfo.swift; sourceTree = "<group>"; };
|
||||||
88CDE06F2A28AEA300114294 /* TemperatureMeasurement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemperatureMeasurement.swift; sourceTree = "<group>"; };
|
88CDE06F2A28AEA300114294 /* TemperatureMeasurement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemperatureMeasurement.swift; sourceTree = "<group>"; };
|
||||||
88CDE0712A28AEB900114294 /* TemperatureDataTransferDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemperatureDataTransferDelegate.swift; sourceTree = "<group>"; };
|
|
||||||
88CDE0732A28AEE500114294 /* DeviceManagerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceManagerDelegate.swift; sourceTree = "<group>"; };
|
88CDE0732A28AEE500114294 /* DeviceManagerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceManagerDelegate.swift; sourceTree = "<group>"; };
|
||||||
88CDE0752A28AF0900114294 /* TemperatureValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemperatureValue.swift; sourceTree = "<group>"; };
|
88CDE0752A28AF0900114294 /* TemperatureValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemperatureValue.swift; sourceTree = "<group>"; };
|
||||||
88CDE0772A28AF2C00114294 /* TemperatureSensor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemperatureSensor.swift; sourceTree = "<group>"; };
|
88CDE0772A28AF2C00114294 /* TemperatureSensor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemperatureSensor.swift; sourceTree = "<group>"; };
|
||||||
@ -81,9 +77,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
88404DD02A2E718B00D30244 /* BinaryCodable in Frameworks */,
|
88404DD02A2E718B00D30244 /* BinaryCodable in Frameworks */,
|
||||||
E253A9272A2CA48A00EC6B28 /* SQLite in Frameworks */,
|
|
||||||
88CDE0662A25D08F00114294 /* SFSafeSymbols in Frameworks */,
|
88CDE0662A25D08F00114294 /* SFSafeSymbols in Frameworks */,
|
||||||
88CDE06B2A2899C900114294 /* BottomSheet in Frameworks */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -143,7 +137,6 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
88CDE06F2A28AEA300114294 /* TemperatureMeasurement.swift */,
|
88CDE06F2A28AEA300114294 /* TemperatureMeasurement.swift */,
|
||||||
88CDE0712A28AEB900114294 /* TemperatureDataTransferDelegate.swift */,
|
|
||||||
88CDE0622A253AD900114294 /* TemperatureDataTransfer.swift */,
|
88CDE0622A253AD900114294 /* TemperatureDataTransfer.swift */,
|
||||||
88CDE0752A28AF0900114294 /* TemperatureValue.swift */,
|
88CDE0752A28AF0900114294 /* TemperatureValue.swift */,
|
||||||
88CDE0772A28AF2C00114294 /* TemperatureSensor.swift */,
|
88CDE0772A28AF2C00114294 /* TemperatureSensor.swift */,
|
||||||
@ -208,8 +201,6 @@
|
|||||||
name = TempTrack;
|
name = TempTrack;
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
88CDE0652A25D08F00114294 /* SFSafeSymbols */,
|
88CDE0652A25D08F00114294 /* SFSafeSymbols */,
|
||||||
88CDE06A2A2899C900114294 /* BottomSheet */,
|
|
||||||
E253A9262A2CA48A00EC6B28 /* SQLite */,
|
|
||||||
88404DCF2A2E718B00D30244 /* BinaryCodable */,
|
88404DCF2A2E718B00D30244 /* BinaryCodable */,
|
||||||
);
|
);
|
||||||
productName = TempTrack;
|
productName = TempTrack;
|
||||||
@ -242,8 +233,6 @@
|
|||||||
mainGroup = 88CDE0422A2508E800114294;
|
mainGroup = 88CDE0422A2508E800114294;
|
||||||
packageReferences = (
|
packageReferences = (
|
||||||
88CDE0642A25D08F00114294 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */,
|
88CDE0642A25D08F00114294 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */,
|
||||||
88CDE0692A2899C900114294 /* XCRemoteSwiftPackageReference "bottom-sheet" */,
|
|
||||||
E253A9252A2CA48900EC6B28 /* XCRemoteSwiftPackageReference "SQLite" */,
|
|
||||||
88404DCE2A2E718B00D30244 /* XCRemoteSwiftPackageReference "BinaryCodable" */,
|
88404DCE2A2E718B00D30244 /* XCRemoteSwiftPackageReference "BinaryCodable" */,
|
||||||
);
|
);
|
||||||
productRefGroup = 88CDE04C2A2508E900114294 /* Products */;
|
productRefGroup = 88CDE04C2A2508E900114294 /* Products */;
|
||||||
@ -281,7 +270,6 @@
|
|||||||
88CDE05D2A250F3C00114294 /* DeviceManager.swift in Sources */,
|
88CDE05D2A250F3C00114294 /* DeviceManager.swift in Sources */,
|
||||||
88404DDF2A2F68E100D30244 /* TemperatureDayOverview.swift in Sources */,
|
88404DDF2A2F68E100D30244 /* TemperatureDayOverview.swift in Sources */,
|
||||||
88CDE04F2A2508E900114294 /* TempTrackApp.swift in Sources */,
|
88CDE04F2A2508E900114294 /* TempTrackApp.swift in Sources */,
|
||||||
88CDE0722A28AEB900114294 /* TemperatureDataTransferDelegate.swift in Sources */,
|
|
||||||
88CDE0782A28AF2C00114294 /* TemperatureSensor.swift in Sources */,
|
88CDE0782A28AF2C00114294 /* TemperatureSensor.swift in Sources */,
|
||||||
88CDE0682A2698B400114294 /* TemperatureStorage.swift in Sources */,
|
88CDE0682A2698B400114294 /* TemperatureStorage.swift in Sources */,
|
||||||
88404DE92A31F7D500D30244 /* Data+Extensions.swift in Sources */,
|
88404DE92A31F7D500D30244 /* Data+Extensions.swift in Sources */,
|
||||||
@ -521,22 +509,6 @@
|
|||||||
minimumVersion = 4.0.0;
|
minimumVersion = 4.0.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
88CDE0692A2899C900114294 /* XCRemoteSwiftPackageReference "bottom-sheet" */ = {
|
|
||||||
isa = XCRemoteSwiftPackageReference;
|
|
||||||
repositoryURL = "https://github.com/weitieda/bottom-sheet";
|
|
||||||
requirement = {
|
|
||||||
kind = upToNextMajorVersion;
|
|
||||||
minimumVersion = 1.0.0;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
E253A9252A2CA48900EC6B28 /* XCRemoteSwiftPackageReference "SQLite" */ = {
|
|
||||||
isa = XCRemoteSwiftPackageReference;
|
|
||||||
repositoryURL = "https://github.com/stephencelis/SQLite.swift";
|
|
||||||
requirement = {
|
|
||||||
kind = upToNextMajorVersion;
|
|
||||||
minimumVersion = 0.14.1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
/* End XCRemoteSwiftPackageReference section */
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency section */
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
@ -550,16 +522,6 @@
|
|||||||
package = 88CDE0642A25D08F00114294 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */;
|
package = 88CDE0642A25D08F00114294 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */;
|
||||||
productName = SFSafeSymbols;
|
productName = SFSafeSymbols;
|
||||||
};
|
};
|
||||||
88CDE06A2A2899C900114294 /* BottomSheet */ = {
|
|
||||||
isa = XCSwiftPackageProductDependency;
|
|
||||||
package = 88CDE0692A2899C900114294 /* XCRemoteSwiftPackageReference "bottom-sheet" */;
|
|
||||||
productName = BottomSheet;
|
|
||||||
};
|
|
||||||
E253A9262A2CA48A00EC6B28 /* SQLite */ = {
|
|
||||||
isa = XCSwiftPackageProductDependency;
|
|
||||||
package = E253A9252A2CA48900EC6B28 /* XCRemoteSwiftPackageReference "SQLite" */;
|
|
||||||
productName = SQLite;
|
|
||||||
};
|
|
||||||
/* End XCSwiftPackageProductDependency section */
|
/* End XCSwiftPackageProductDependency section */
|
||||||
};
|
};
|
||||||
rootObject = 88CDE0432A2508E800114294 /* Project object */;
|
rootObject = 88CDE0432A2508E800114294 /* Project object */;
|
||||||
|
@ -9,31 +9,13 @@
|
|||||||
"version" : "2.0.0"
|
"version" : "2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"identity" : "bottom-sheet",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/weitieda/bottom-sheet",
|
|
||||||
"state" : {
|
|
||||||
"revision" : "6b21007153365235418f3943a960a1f9546592e0",
|
|
||||||
"version" : "1.0.12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"identity" : "sfsafesymbols",
|
"identity" : "sfsafesymbols",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/SFSafeSymbols/SFSafeSymbols",
|
"location" : "https://github.com/SFSafeSymbols/SFSafeSymbols",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "2bcd249b49178247e6b52bac7d67d6e338a40cee",
|
"revision" : "7cca2d60925876b5953a2cf7341cd80fbeac983c",
|
||||||
"version" : "4.1.0"
|
"version" : "4.1.1"
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identity" : "sqlite.swift",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/stephencelis/SQLite.swift",
|
|
||||||
"state" : {
|
|
||||||
"revision" : "7a2e3cd27de56f6d396e84f63beefd0267b55ccb",
|
|
||||||
"version" : "0.14.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
Binary file not shown.
@ -3,15 +3,18 @@ import SwiftUI
|
|||||||
|
|
||||||
final class BluetoothClient: ObservableObject {
|
final class BluetoothClient: ObservableObject {
|
||||||
|
|
||||||
weak var delegate: TemperatureDataTransferDelegate?
|
|
||||||
|
|
||||||
private let updateInterval = 3.0
|
private let updateInterval = 3.0
|
||||||
|
|
||||||
|
private let minimumOffsetToUpdateDeviceClock = 5.0
|
||||||
|
|
||||||
private let connection = DeviceManager()
|
private let connection = DeviceManager()
|
||||||
|
|
||||||
init(deviceInfo: DeviceInfo? = nil) {
|
private let storage: TemperatureStorage
|
||||||
connection.delegate = self
|
|
||||||
|
init(storage: TemperatureStorage, deviceInfo: DeviceInfo? = nil) {
|
||||||
|
self.storage = storage
|
||||||
self.deviceInfo = deviceInfo
|
self.deviceInfo = deviceInfo
|
||||||
|
connection.delegate = self
|
||||||
}
|
}
|
||||||
|
|
||||||
func connect() -> Bool {
|
func connect() -> Bool {
|
||||||
@ -111,16 +114,17 @@ final class BluetoothClient: ObservableObject {
|
|||||||
// MARK: Device time
|
// MARK: Device time
|
||||||
|
|
||||||
private func updateDeviceTimeIfNeeded() {
|
private func updateDeviceTimeIfNeeded() {
|
||||||
guard let info = deviceInfo else {
|
guard let deviceInfo else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guard !info.hasDeviceStartTimeSet else {
|
guard !deviceInfo.hasDeviceStartTimeSet || deviceInfo.clockOffset > minimumOffsetToUpdateDeviceClock else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard !openRequests.contains(where: { if case .setDeviceStartTime = $0 { return true }; return false }) else {
|
guard !openRequests.contains(where: { if case .setDeviceStartTime = $0 { return true }; return false }) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let time = info.deviceStartTime.seconds
|
let time = deviceInfo.deviceStartTime.seconds
|
||||||
addRequest(.setDeviceStartTime(deviceStartTimeSeconds: time))
|
addRequest(.setDeviceStartTime(deviceStartTimeSeconds: time))
|
||||||
print("Setting device start time to \(time) s (\(Date().seconds) current)")
|
print("Setting device start time to \(time) s (\(Date().seconds) current)")
|
||||||
}
|
}
|
||||||
@ -144,7 +148,6 @@ final class BluetoothClient: ObservableObject {
|
|||||||
|
|
||||||
let transfer = TemperatureDataTransfer(info: info)
|
let transfer = TemperatureDataTransfer(info: info)
|
||||||
runningTransfer = transfer
|
runningTransfer = transfer
|
||||||
runningTransfer?.delegate = delegate
|
|
||||||
let next = transfer.nextRequest()
|
let next = transfer.nextRequest()
|
||||||
addRequest(next)
|
addRequest(next)
|
||||||
return true
|
return true
|
||||||
@ -171,12 +174,13 @@ final class BluetoothClient: ObservableObject {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.deviceInfo = newInfo
|
self.deviceInfo = newInfo
|
||||||
guard let runningTransfer else {
|
if let runningTransfer {
|
||||||
return
|
|
||||||
}
|
|
||||||
runningTransfer.update(info: newInfo)
|
runningTransfer.update(info: newInfo)
|
||||||
let next = runningTransfer.nextRequest()
|
let next = runningTransfer.nextRequest()
|
||||||
addRequest(next)
|
addRequest(next)
|
||||||
|
} else if newInfo.numberOfStoredMeasurements > 0 {
|
||||||
|
collectRecordedData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,14 +230,25 @@ extension BluetoothClient: DeviceManagerDelegate {
|
|||||||
case .getRecordingData(let offset, let count):
|
case .getRecordingData(let offset, let count):
|
||||||
didReceive(data: payload, offset: offset, count: count)
|
didReceive(data: payload, offset: offset, count: count)
|
||||||
case .clearRecordingBuffer:
|
case .clearRecordingBuffer:
|
||||||
runningTransfer?.completeTransfer()
|
didClearDeviceStorage()
|
||||||
runningTransfer = nil
|
|
||||||
case .setDeviceStartTime:
|
case .setDeviceStartTime:
|
||||||
print("Device time set")
|
print("Device time set")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func didClearDeviceStorage() {
|
||||||
|
guard let runningTransfer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
runningTransfer.completeTransfer()
|
||||||
|
storage.add(runningTransfer.measurements)
|
||||||
|
self.runningTransfer = nil
|
||||||
|
|
||||||
|
updateDeviceTimeIfNeeded()
|
||||||
|
}
|
||||||
|
|
||||||
func deviceManager(didChangeState state: DeviceState) {
|
func deviceManager(didChangeState state: DeviceState) {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.deviceState = state
|
self.deviceState = state
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import SFSafeSymbols
|
import SFSafeSymbols
|
||||||
import BottomSheet
|
|
||||||
|
|
||||||
struct ContentView: View {
|
struct ContentView: View {
|
||||||
|
|
||||||
@ -144,9 +143,11 @@ struct ContentView: View {
|
|||||||
|
|
||||||
struct ContentView_Previews: PreviewProvider {
|
struct ContentView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
|
let storage = TemperatureStorage(lastMeasurements: TemperatureMeasurement.mockData)
|
||||||
|
let client = BluetoothClient(storage: storage, deviceInfo: .mock)
|
||||||
ContentView()
|
ContentView()
|
||||||
.environmentObject(TemperatureStorage(lastMeasurements: TemperatureMeasurement.mockData))
|
.environmentObject(storage)
|
||||||
.environmentObject(BluetoothClient(deviceInfo: .mock))
|
.environmentObject(client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,11 @@ final class TemperatureStorage: ObservableObject {
|
|||||||
@AppStorage("newestDate")
|
@AppStorage("newestDate")
|
||||||
private var newestMeasurementTime: Int = 0
|
private var newestMeasurementTime: Int = 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
The date of the latest measurement.
|
||||||
|
|
||||||
|
Incoming data older than this date will be rejected to prevent duplicate measurements
|
||||||
|
*/
|
||||||
private var newestMeasurementDate: Date {
|
private var newestMeasurementDate: Date {
|
||||||
get {
|
get {
|
||||||
Date(seconds: newestMeasurementTime)
|
Date(seconds: newestMeasurementTime)
|
||||||
@ -30,8 +35,6 @@ final class TemperatureStorage: ObservableObject {
|
|||||||
@Published
|
@Published
|
||||||
var dailyMeasurementCounts: [MeasurementDailyCount] = []
|
var dailyMeasurementCounts: [MeasurementDailyCount] = []
|
||||||
|
|
||||||
private var unsavedMeasurements: [TemperatureMeasurement] = []
|
|
||||||
|
|
||||||
private let fileNameFormatter: DateFormatter
|
private let fileNameFormatter: DateFormatter
|
||||||
|
|
||||||
private let storageFolder: URL
|
private let storageFolder: URL
|
||||||
@ -99,6 +102,12 @@ final class TemperatureStorage: ObservableObject {
|
|||||||
recentMeasurements = yesterdayValues + todayValues
|
recentMeasurements = yesterdayValues + todayValues
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func updateLastMeasurements(_ measurements: [TemperatureMeasurement]) {
|
||||||
|
let startDate = Date().addingTimeInterval(-lastValueInterval).seconds
|
||||||
|
let new = recentMeasurements + measurements
|
||||||
|
recentMeasurements = Array(new.drop { $0.id < startDate })
|
||||||
|
}
|
||||||
|
|
||||||
private func loadMeasurements(for date: Date) -> [TemperatureMeasurement] {
|
private func loadMeasurements(for date: Date) -> [TemperatureMeasurement] {
|
||||||
loadMeasurements(from: fileName(for: date))
|
loadMeasurements(from: fileName(for: date))
|
||||||
}
|
}
|
||||||
@ -124,13 +133,19 @@ final class TemperatureStorage: ObservableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func save() {
|
func add(_ measurements: [TemperatureMeasurement]) {
|
||||||
for (dateIndex, values) in unsavedMeasurements.splitByDate() {
|
let lastDate = self.newestMeasurementDate.seconds
|
||||||
|
let newValues = measurements
|
||||||
|
.filter { $0.id > lastDate }
|
||||||
|
.splitByDate()
|
||||||
|
|
||||||
|
for (dateIndex, values) in newValues {
|
||||||
let count = saveNew(values, for: dateIndex)
|
let count = saveNew(values, for: dateIndex)
|
||||||
print("Day \(dateIndex): \(count) of \(values.count) saved")
|
setDailyCount(count, for: dateIndex)
|
||||||
|
print("Day \(dateIndex): \(count) values")
|
||||||
}
|
}
|
||||||
unsavedMeasurements = []
|
|
||||||
saveDailyCounts()
|
saveDailyCounts()
|
||||||
|
updateLastMeasurements(measurements)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,21 +153,9 @@ final class TemperatureStorage: ObservableObject {
|
|||||||
*/
|
*/
|
||||||
private func saveNew(_ measurements: [TemperatureMeasurement], for dateIndex: Int) -> Int {
|
private func saveNew(_ measurements: [TemperatureMeasurement], for dateIndex: Int) -> Int {
|
||||||
let fileName = fileName(for: dateIndex)
|
let fileName = fileName(for: dateIndex)
|
||||||
var existing = loadMeasurements(from: fileName)
|
let values = loadMeasurements(from: fileName) + measurements
|
||||||
guard !existing.isEmpty else {
|
save(values, for: fileName)
|
||||||
save(measurements, for: fileName)
|
return values.count
|
||||||
setDailyCount(measurements.count, for: dateIndex)
|
|
||||||
return measurements.count
|
|
||||||
}
|
|
||||||
var inserted = 0
|
|
||||||
for value in measurements {
|
|
||||||
if existing.insert(value) {
|
|
||||||
inserted += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
save(existing, for: fileName)
|
|
||||||
setDailyCount(existing.count, for: dateIndex)
|
|
||||||
return inserted
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func save(_ measurements: [TemperatureMeasurement], for fileName: String) {
|
private func save(_ measurements: [TemperatureMeasurement], for fileName: String) {
|
||||||
@ -239,23 +242,6 @@ final class TemperatureStorage: ObservableObject {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TemperatureStorage: TemperatureDataTransferDelegate {
|
|
||||||
|
|
||||||
func didReceiveRecording(_ measurement: TemperatureMeasurement) {
|
|
||||||
// Add to unsaved measurements
|
|
||||||
if unsavedMeasurements.insert(measurement) {
|
|
||||||
incrementCount(for: measurement.date.dateIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add to last measurements
|
|
||||||
recentMeasurements.insert(measurement)
|
|
||||||
}
|
|
||||||
|
|
||||||
func saveAfterTransfer() {
|
|
||||||
save()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension Array where Element == TemperatureMeasurement {
|
private extension Array where Element == TemperatureMeasurement {
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
let storage = TemperatureStorage()
|
private let storage = TemperatureStorage()
|
||||||
let bluetoothClient = BluetoothClient()
|
private let bluetoothClient: BluetoothClient = {
|
||||||
|
.init(storage: storage)
|
||||||
|
}()
|
||||||
|
|
||||||
@main
|
@main
|
||||||
struct TempTrackApp: App {
|
struct TempTrackApp: App {
|
||||||
@ -11,9 +13,6 @@ struct TempTrackApp: App {
|
|||||||
ContentView()
|
ContentView()
|
||||||
.environmentObject(storage)
|
.environmentObject(storage)
|
||||||
.environmentObject(bluetoothClient)
|
.environmentObject(bluetoothClient)
|
||||||
.onAppear {
|
|
||||||
bluetoothClient.delegate = storage
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,6 @@ final class TemperatureDataTransfer {
|
|||||||
|
|
||||||
private let interval: Int
|
private let interval: Int
|
||||||
|
|
||||||
weak var delegate: TemperatureDataTransferDelegate?
|
|
||||||
|
|
||||||
private var dataBuffer: Data = Data()
|
private var dataBuffer: Data = Data()
|
||||||
|
|
||||||
private(set) var currentByteIndex = 0
|
private(set) var currentByteIndex = 0
|
||||||
@ -18,7 +16,10 @@ final class TemperatureDataTransfer {
|
|||||||
|
|
||||||
private var numberOfRecordingsInCurrentTransfer = 0
|
private var numberOfRecordingsInCurrentTransfer = 0
|
||||||
|
|
||||||
private(set) var lastRecording: TemperatureMeasurement = .init(sensor0: .notFound, sensor1: .notFound, date: .now)
|
var measurements: [TemperatureMeasurement] = []
|
||||||
|
|
||||||
|
/// The last temperatures to calculate relative values
|
||||||
|
private var lastRecording: TemperatureMeasurement = .init(sensor0: .notFound, sensor1: .notFound, date: .now)
|
||||||
|
|
||||||
private var dateOfNextRecording: Date {
|
private var dateOfNextRecording: Date {
|
||||||
startDateOfCurrentTransfer.addingTimeInterval(TimeInterval(numberOfRecordingsInCurrentTransfer * interval))
|
startDateOfCurrentTransfer.addingTimeInterval(TimeInterval(numberOfRecordingsInCurrentTransfer * interval))
|
||||||
@ -78,7 +79,6 @@ final class TemperatureDataTransfer {
|
|||||||
|
|
||||||
func completeTransfer() {
|
func completeTransfer() {
|
||||||
processBytes()
|
processBytes()
|
||||||
delegate?.saveAfterTransfer()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func addRelative(byte: UInt8) {
|
private func addRelative(byte: UInt8) {
|
||||||
@ -100,7 +100,7 @@ final class TemperatureDataTransfer {
|
|||||||
lastRecording.sensor1 = measurement.sensor1
|
lastRecording.sensor1 = measurement.sensor1
|
||||||
}
|
}
|
||||||
lastRecording.id = measurement.id
|
lastRecording.id = measurement.id
|
||||||
delegate?.didReceiveRecording(measurement)
|
measurements.append(measurement)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func convertTemp(value: UInt8, relativeTo previous: TemperatureValue) -> TemperatureValue {
|
private func convertTemp(value: UInt8, relativeTo previous: TemperatureValue) -> TemperatureValue {
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
|
|
||||||
protocol TemperatureDataTransferDelegate: AnyObject {
|
|
||||||
|
|
||||||
func didReceiveRecording(_ measurement: TemperatureMeasurement)
|
|
||||||
|
|
||||||
func saveAfterTransfer()
|
|
||||||
}
|
|
@ -6,6 +6,7 @@ struct TemperatureMeasurement: Identifiable {
|
|||||||
|
|
||||||
var sensor1: TemperatureValue
|
var sensor1: TemperatureValue
|
||||||
|
|
||||||
|
/// The seconds since 1970
|
||||||
var id: Int
|
var id: Int
|
||||||
|
|
||||||
var date: Date {
|
var date: Date {
|
||||||
@ -18,7 +19,7 @@ struct TemperatureMeasurement: Identifiable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var secondsToNow: Int {
|
var secondsToNow: Int {
|
||||||
Date().seconds - id
|
id - Date().seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
var maximumValue: Double? {
|
var maximumValue: Double? {
|
||||||
@ -172,7 +173,7 @@ extension TemperatureMeasurement {
|
|||||||
TemperatureMeasurement(
|
TemperatureMeasurement(
|
||||||
sensor0: .init(value: $0.element.0),
|
sensor0: .init(value: $0.element.0),
|
||||||
sensor1: .init(value: $0.element.1),
|
sensor1: .init(value: $0.element.1),
|
||||||
id: seconds + $0.offset * 60)
|
id: seconds + ($0.offset - temps.count) * 60)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user