Skip to content

Commit

Permalink
feat: Dynamic dashboard, session manager class
Browse files Browse the repository at this point in the history
  • Loading branch information
sadeelmu committed May 28, 2024
1 parent 9b8de90 commit 69089d0
Show file tree
Hide file tree
Showing 13 changed files with 551 additions and 344 deletions.
28 changes: 12 additions & 16 deletions Asthmaguard.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
12E0B0922BF60F89003E18D6 /* AnalyticsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12E0B0912BF60F89003E18D6 /* AnalyticsView.swift */; };
12EAA2DE2BE8C50400C0A1DB /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12EAA2DD2BE8C50400C0A1DB /* LocationManager.swift */; };
12EEFB042BB05FF3003053AB /* SettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12EEFB032BB05FF2003053AB /* SettingsScreen.swift */; };
12FC1DF42C03ABA70002F50D /* AsthmaTriggerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12FC1DF32C03ABA70002F50D /* AsthmaTriggerModel.swift */; };
12FC1DFC2C044CA30002F50D /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12FC1DFB2C044CA30002F50D /* SessionManager.swift */; };
12FC1DFE2C0450BE0002F50D /* AsthmaThreatModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12FC1DFD2C0450BE0002F50D /* AsthmaThreatModel.swift */; };
36495D3769F738E52AE09E55 /* Pods_AsthmaguardTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A473D07D19F4891C0EC3EA46 /* Pods_AsthmaguardTests.framework */; };
3FF0674C489C293D17AD478C /* Pods_Asthmaguard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D86664A7B056AD9D5A4532B /* Pods_Asthmaguard.framework */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -104,6 +107,9 @@
12E0B0912BF60F89003E18D6 /* AnalyticsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsView.swift; sourceTree = "<group>"; };
12EAA2DD2BE8C50400C0A1DB /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = "<group>"; };
12EEFB032BB05FF2003053AB /* SettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreen.swift; sourceTree = "<group>"; };
12FC1DF32C03ABA70002F50D /* AsthmaTriggerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsthmaTriggerModel.swift; sourceTree = "<group>"; };
12FC1DFB2C044CA30002F50D /* SessionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionManager.swift; sourceTree = "<group>"; };
12FC1DFD2C0450BE0002F50D /* AsthmaThreatModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsthmaThreatModel.swift; sourceTree = "<group>"; };
47517DB559739E3571B31F22 /* Pods-AsthmaguardTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsthmaguardTests.debug.xcconfig"; path = "Target Support Files/Pods-AsthmaguardTests/Pods-AsthmaguardTests.debug.xcconfig"; sourceTree = "<group>"; };
5810EE9B8C5719A14118CF19 /* Pods-AsthmaguardTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AsthmaguardTests.release.xcconfig"; path = "Target Support Files/Pods-AsthmaguardTests/Pods-AsthmaguardTests.release.xcconfig"; sourceTree = "<group>"; };
711CB4D76AD25FABB75C23A2 /* Pods-Asthmaguard.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Asthmaguard.debug.xcconfig"; path = "Target Support Files/Pods-Asthmaguard/Pods-Asthmaguard.debug.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -218,16 +224,15 @@
1276E3702B7ACD8F002CBACB /* Data */ = {
isa = PBXGroup;
children = (
12E1EDEE2B95A9870016EDDE /* Responses */,
12E1EDEB2B95A9270016EDDE /* Models */,
12E1EDE92B95A8FF0016EDDE /* Repos */,
);
path = Data;
sourceTree = "<group>";
};
1276E3722B7ACD99002CBACB /* Business */ = {
isa = PBXGroup;
children = (
12FC1DFB2C044CA30002F50D /* SessionManager.swift */,
12EAA2DD2BE8C50400C0A1DB /* LocationManager.swift */,
12E1EDE82B95A73B0016EDDE /* Usecases */,
);
Expand Down Expand Up @@ -302,16 +307,11 @@
path = Usecases;
sourceTree = "<group>";
};
12E1EDE92B95A8FF0016EDDE /* Repos */ = {
isa = PBXGroup;
children = (
);
path = Repos;
sourceTree = "<group>";
};
12E1EDEB2B95A9270016EDDE /* Models */ = {
isa = PBXGroup;
children = (
12FC1DF32C03ABA70002F50D /* AsthmaTriggerModel.swift */,
12FC1DFD2C0450BE0002F50D /* AsthmaThreatModel.swift */,
);
path = Models;
sourceTree = "<group>";
Expand All @@ -332,13 +332,6 @@
path = DataNetwork;
sourceTree = "<group>";
};
12E1EDEE2B95A9870016EDDE /* Responses */ = {
isa = PBXGroup;
children = (
);
path = Responses;
sourceTree = "<group>";
};
12E1EDEF2B95A9BD0016EDDE /* Endpoints */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -545,7 +538,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
12FC1DF42C03ABA70002F50D /* AsthmaTriggerModel.swift in Sources */,
12C3F7D22BB576C6008B43ED /* CustomBioData.swift in Sources */,
12FC1DFC2C044CA30002F50D /* SessionManager.swift in Sources */,
12EEFB042BB05FF3003053AB /* SettingsScreen.swift in Sources */,
121A50D72BBA364500198997 /* BreathingExerciseScreen.swift in Sources */,
1236025C2BD8E1A700A2C657 /* DatabaseSetUp.swift in Sources */,
Expand All @@ -567,6 +562,7 @@
12E0B0922BF60F89003E18D6 /* AnalyticsView.swift in Sources */,
126FC27C2BA30B1B00BE1FDD /* DashboardView.swift in Sources */,
12E0B0902BF60EBE003E18D6 /* CompanionSettingScreen.swift in Sources */,
12FC1DFE2C0450BE0002F50D /* AsthmaThreatModel.swift in Sources */,
12BAFE2A2BA0428E003E7980 /* SurveyHelper.swift in Sources */,
121A50D92BBA401600198997 /* CustomTabView.swift in Sources */,
12E0B08E2BF60E5E003E18D6 /* CompanionDashboardView.swift in Sources */,
Expand Down
26 changes: 26 additions & 0 deletions Asthmaguard/Business/SessionManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// SessionManager.swift
// Asthmaguard
//
// Created by Sadeel Muwahed on 27/05/2024.
//

class SessionManager {
static let shared = SessionManager()

private var currentToken: Int?

private init() { }

func login(token: Int) {
self.currentToken = token
}

func logout() {
self.currentToken = nil
}

func getCurrentToken() -> Int? {
return self.currentToken
}
}
187 changes: 114 additions & 73 deletions Asthmaguard/Business/Usecases/AsthmaThreatCalculator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,29 @@ import Foundation
import CoreLocation
import HealthKit

class AsthmaThreatCalculatorUseCase {
public class AsthmaThreatCalculatorUseCase {
private let locationManager = LocationManager.shared
private let weatherKitData = WeatherKitData()
private let healthStore = HKHealthStore()
private let databaseManager = DatabaseManager.shared

var weightedEnvironmentalRisk: Double = 0.0
var weightedBioSignalRisk: Double = 0.0

var weightedHeartRateSeverity: Double = 0.0
var weightedRespiratoryRateSeverity: Double = 0.0
var weightedOxygenSaturationSeverity: Double = 0.0
var weightedAirQualitySeverity: Double = 0.0
var weightedPollenSeverity: Double = 0.0
var weightedHumiditySeverity: Double = 0.0
var weightedCloudCoverSeverity: Double = 0.0
var weightedTemperatureSeverity: Double = 0.0
var totalWeightedSeverity: Double = 0.0

init() {
startMonitoring()
}

// MARK: - Monitoring

func startMonitoring() {
Expand All @@ -25,36 +42,60 @@ class AsthmaThreatCalculatorUseCase {

// MARK: - Data Fetching

private func fetchDataAndCalculateAsthmaSeverity() {
self.fetchBiosignalData { biosignalSamples in
guard let biosignalSamples = biosignalSamples else {
print("Failed to fetch biosignal data.")
func fetchDataAndCalculateAsthmaSeverity() {
guard let patientToken = getPatientToken() else {
print("Current token not available.")
return
}

databaseManager.fetchUserID(byToken: patientToken) { userID in
guard let userID = userID else {
print("User ID not found for token: \(patientToken).")
return
}

self.fetchBiosignalData { biosignalSamples in
guard let biosignalSamples = biosignalSamples else {
print("Failed to fetch biosignal data.")
return
}

self.fetchEnvironmentalData { airQualityData, pollenForecastData in
guard let airQualityData = airQualityData, let pollenForecastData = pollenForecastData else {
print("Failed to fetch environmental data.")
return
}

self.fetchWeatherData { weatherData in
guard let weatherData = weatherData else {
print("Failed to fetch weather data.")
return
}

self.calculateAsthmaSeverity(userID: userID, biosignalSamples: biosignalSamples, environmentalData: (airQualityData, pollenForecastData), weatherData: weatherData)
}
}
}
}
}

func fetchData() {
guard let patientToken = getPatientToken() else {
print("Current username not available.")
return
}

databaseManager.fetchUserID(byToken: patientToken) { userID in
guard let userID = userID else {
print("User ID not found for username: \(patientToken).")
return
}

self.fetchEnvironmentalData { airQualityData, pollenForecastData in
guard let airQualityData = airQualityData, let pollenForecastData = pollenForecastData else {
print("Failed to fetch environmental data.")
return
}

self.fetchWeatherData { weatherData in
guard let weatherData = weatherData else {
print("Failed to fetch weather data.")
return
self.fetchBiosignalData { biosignalSamples in
self.fetchEnvironmentalData { airQualityData, pollenForecastData in
self.fetchWeatherData { weatherData in
print("airQuality data \(String(describing: airQualityData)), pollenForecastData \(String(describing: pollenForecastData)), weatherData \(String(describing: weatherData)), bioSignalData \(String(describing: biosignalSamples))")
}

self.calculateAsthmaSeverity(biosignalSamples: biosignalSamples, environmentalData: (airQualityData, pollenForecastData), weatherData: weatherData)
}
}
}
}

func fetchData() {
self.fetchBiosignalData { biosignalSamples in
self.fetchEnvironmentalData { airQualityData, pollenForecastData in
self.fetchWeatherData { weatherData in
print("airQuality data \(String(describing: airQualityData)), pollenForecastData \(String(describing: pollenForecastData)), weatherData \(String(describing: weatherData)), bioSignalData \(String(describing: biosignalSamples))")
}
}
}
Expand Down Expand Up @@ -120,36 +161,59 @@ class AsthmaThreatCalculatorUseCase {

// MARK: - Asthma Severity Calculation

private func calculateAsthmaSeverity(biosignalSamples: [HKQuantitySample], environmentalData: (EnviromentalData.AirQualityData?, EnviromentalData.PollenForecastData?), weatherData: WeatherKitData.WeatherData) {
let userID = 1 // Example userID, replace with actual user ID
private func calculateAsthmaSeverity(userID: Int, biosignalSamples: [HKQuantitySample], environmentalData: (EnviromentalData.AirQualityData?, EnviromentalData.PollenForecastData?), weatherData: WeatherKitData.WeatherData) {
databaseManager.fetchAsthmaTriggers(forUserID: userID) { triggerGrades in
let heartRateSeverity = HealthDataAnalyzer.calculateHeartRateSeverity(samples: biosignalSamples)
let respiratoryRateSeverity = HealthDataAnalyzer.calculateRespiratoryRateSeverity(samples: biosignalSamples)
let oxygenSaturationSeverity = HealthDataAnalyzer.calculateOxygenSaturationSeverity(samples: biosignalSamples)

var airQualitySeverity = 0.0
if let airQualityData = environmentalData.0 {
airQualitySeverity = self.calculateAQISeverity(aqiLevel: airQualityData.universalAQI)
}

let airQualitySeverity = self.calculateAQISeverity(aqiLevel: environmentalData.0?.universalAQI)
let pollenSeverity = self.calculatePollenSeverity(pollenForecastData: environmentalData.1)
let humiditySeverity = self.weatherKitData.calculateHumiditySeverity(humidity: weatherData.humidity)
let cloudCoverSeverity = self.weatherKitData.calculateCloudCoverSeverity(cloudCover: weatherData.cloudCover)
let temperatureSeverity = self.weatherKitData.calculateTemperatureSeverity(temperature: weatherData.temperature)

let weightedSeverity = self.calculateWeightedSeverity(
heartRateSeverity: heartRateSeverity,
respiratoryRateSeverity: respiratoryRateSeverity,
oxygenSaturationSeverity: oxygenSaturationSeverity,
airQualitySeverity: airQualitySeverity,
pollenSeverity: pollenSeverity,
humiditySeverity: humiditySeverity,
cloudCoverSeverity: cloudCoverSeverity,
temperatureSeverity: temperatureSeverity,
triggerGrades: triggerGrades
)
self.weightedHeartRateSeverity = heartRateSeverity * Double(triggerGrades[0])
self.weightedRespiratoryRateSeverity = respiratoryRateSeverity * Double(triggerGrades[1])
self.weightedOxygenSaturationSeverity = oxygenSaturationSeverity * Double(triggerGrades[2])
self.weightedAirQualitySeverity = airQualitySeverity * Double(triggerGrades[3])
self.weightedPollenSeverity = pollenSeverity * Double(triggerGrades[4])
self.weightedHumiditySeverity = humiditySeverity * Double(triggerGrades[5])
self.weightedCloudCoverSeverity = cloudCoverSeverity * Double(triggerGrades[6])
self.weightedTemperatureSeverity = temperatureSeverity * Double(triggerGrades[7])

print("Asthma Threat: \(Int(weightedSeverity * 100))%")
let biosignalWeightsTotal = Double(triggerGrades[0] + triggerGrades[1] + triggerGrades[2])
let environmentalWeightsTotal = Double(triggerGrades[3] + triggerGrades[4] + triggerGrades[5] + triggerGrades[6] + triggerGrades[7])
let totalWeights = biosignalWeightsTotal + environmentalWeightsTotal

self.weightedBioSignalRisk = (
self.weightedHeartRateSeverity +
self.weightedRespiratoryRateSeverity +
self.weightedOxygenSaturationSeverity
) / biosignalWeightsTotal

self.weightedEnvironmentalRisk = (
self.weightedAirQualitySeverity +
self.weightedPollenSeverity +
self.weightedHumiditySeverity +
self.weightedCloudCoverSeverity +
self.weightedTemperatureSeverity
) / environmentalWeightsTotal

self.totalWeightedSeverity = (
self.weightedHeartRateSeverity +
self.weightedRespiratoryRateSeverity +
self.weightedOxygenSaturationSeverity +
self.weightedAirQualitySeverity +
self.weightedPollenSeverity +
self.weightedHumiditySeverity +
self.weightedCloudCoverSeverity +
self.weightedTemperatureSeverity
) / totalWeights

print("Weighted Environmental Risk: \(self.weightedEnvironmentalRisk)")
print("Weighted BioSignal Risk: \(self.weightedBioSignalRisk)")
print("Total Weighted Severity: \(self.totalWeightedSeverity)")
}
}

Expand Down Expand Up @@ -184,31 +248,8 @@ class AsthmaThreatCalculatorUseCase {
let maxSeverity = pollenTypes.map { categorySeverityMap[$0.indexInfo.category] ?? 0.0 }.max() ?? 0.0
return maxSeverity
}

func calculateWeightedSeverity(
heartRateSeverity: Double,
respiratoryRateSeverity: Double,
oxygenSaturationSeverity: Double,
airQualitySeverity: Double,
pollenSeverity: Double,
humiditySeverity: Double,
cloudCoverSeverity: Double,
temperatureSeverity: Double,
triggerGrades: [Int]
) -> Double {
let totalGrade = Double(triggerGrades.reduce(0, +))

let weightedSeverity = (
(heartRateSeverity * Double(triggerGrades[0])) +
(respiratoryRateSeverity * Double(triggerGrades[1])) +
(oxygenSaturationSeverity * Double(triggerGrades[2])) +
(airQualitySeverity * Double(triggerGrades[3])) +
(pollenSeverity * Double(triggerGrades[4])) +
(humiditySeverity * Double(triggerGrades[5])) +
(cloudCoverSeverity * Double(triggerGrades[6])) +
(temperatureSeverity * Double(triggerGrades[7]))
) / totalGrade

return weightedSeverity
}

private func getPatientToken() -> Int? {
return SessionManager.shared.getCurrentToken()
}
}
2 changes: 1 addition & 1 deletion Asthmaguard/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import SwiftUI
@available(iOS 17.0, *)
struct ContentView: View {
var body: some View {
BreathingExerciseScreen()
RegisterScreen()

}
}
Expand Down
14 changes: 14 additions & 0 deletions Asthmaguard/Data/Models/AsthmaThreatModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// AsthmaThreatModel.swift
// Asthmaguard
//
// Created by Sadeel Muwahed on 27/05/2024.
//

import Foundation

struct AsthmaThreat: Identifiable {
let id = UUID()
let title: String
let risks: Double
}
14 changes: 14 additions & 0 deletions Asthmaguard/Data/Models/AsthmaTriggerModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// AsthmaTrigger.swift
// Asthmaguard
//
// Created by Sadeel Muwahed on 26/05/2024.
//

import Foundation

struct AsthmaTrigger {
let triggerID: Int
let patientID: Int
let grade: Int
}
Loading

0 comments on commit 69089d0

Please sign in to comment.