diff options
-rw-r--r-- | .DS_Store | bin | 6148 -> 6148 bytes | |||
-rw-r--r-- | iCUrHealth.xcodeproj/project.pbxproj | 20 | ||||
-rw-r--r-- | iCUrHealth.xcodeproj/project.xcworkspace/xcuserdata/gsinnott.xcuserdatad/UserInterfaceState.xcuserstate | bin | 0 -> 59939 bytes | |||
-rw-r--r-- | iCUrHealth.xcodeproj/xcuserdata/gsinnott.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist | 134 | ||||
-rw-r--r-- | iCUrHealth/ContentView.swift | 5 | ||||
-rw-r--r-- | iCUrHealth/DataAtAGlance.swift | 4 | ||||
-rw-r--r-- | iCUrHealth/UserCharts.swift | 61 |
7 files changed, 205 insertions, 19 deletions
Binary files differ diff --git a/iCUrHealth.xcodeproj/project.pbxproj b/iCUrHealth.xcodeproj/project.pbxproj index e357555..f2b0d3c 100644 --- a/iCUrHealth.xcodeproj/project.pbxproj +++ b/iCUrHealth.xcodeproj/project.pbxproj @@ -11,11 +11,11 @@ 3E54FF0E2B772F1C00260FCB /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E54FF0D2B772F1C00260FCB /* ContentView.swift */; }; 3E54FF102B772F1E00260FCB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3E54FF0F2B772F1E00260FCB /* Assets.xcassets */; }; 3E54FF142B772F1E00260FCB /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3E54FF132B772F1E00260FCB /* Preview Assets.xcassets */; }; - 3E54FF1C2B7765C200260FCB /* CareKit in Frameworks */ = {isa = PBXBuildFile; productRef = 3E54FF1B2B7765C200260FCB /* CareKit */; }; - 3E54FF1E2B7765C200260FCB /* CareKitStore in Frameworks */ = {isa = PBXBuildFile; productRef = 3E54FF1D2B7765C200260FCB /* CareKitStore */; }; - 3E54FF202B7765C200260FCB /* CareKitUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3E54FF1F2B7765C200260FCB /* CareKitUI */; }; 72C8BC2F2B777369004BAE8B /* UserCharts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72C8BC2E2B777369004BAE8B /* UserCharts.swift */; }; 72C8BC312B77736E004BAE8B /* HealthChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72C8BC302B77736E004BAE8B /* HealthChart.swift */; }; + 72C8BC352B77AEEE004BAE8B /* HealthData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72C8BC322B77AEEE004BAE8B /* HealthData.swift */; }; + 72C8BC362B77AEEE004BAE8B /* DataAtAGlance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72C8BC332B77AEEE004BAE8B /* DataAtAGlance.swift */; }; + 72C8BC372B77AEEE004BAE8B /* DetailedAnalysisView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72C8BC342B77AEEE004BAE8B /* DetailedAnalysisView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -27,6 +27,9 @@ 3E54FF132B772F1E00260FCB /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; }; 72C8BC2E2B777369004BAE8B /* UserCharts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserCharts.swift; sourceTree = "<group>"; }; 72C8BC302B77736E004BAE8B /* HealthChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthChart.swift; sourceTree = "<group>"; }; + 72C8BC322B77AEEE004BAE8B /* HealthData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HealthData.swift; sourceTree = "<group>"; }; + 72C8BC332B77AEEE004BAE8B /* DataAtAGlance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataAtAGlance.swift; sourceTree = "<group>"; }; + 72C8BC342B77AEEE004BAE8B /* DetailedAnalysisView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailedAnalysisView.swift; sourceTree = "<group>"; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -59,9 +62,9 @@ 3E54FF0A2B772F1C00260FCB /* iCUrHealth */ = { isa = PBXGroup; children = ( - 3EAA76182B77A10100DEE6D2 /* DetailedAnalysisView.swift */, - 3E54FF252B778AC200260FCB /* HealthChart.swift */, - 3E54FF232B778ABC00260FCB /* UserCharts.swift */, + 72C8BC332B77AEEE004BAE8B /* DataAtAGlance.swift */, + 72C8BC342B77AEEE004BAE8B /* DetailedAnalysisView.swift */, + 72C8BC322B77AEEE004BAE8B /* HealthData.swift */, 3E54FF0B2B772F1C00260FCB /* iCUrHealthApp.swift */, 3E54FF0D2B772F1C00260FCB /* ContentView.swift */, 72C8BC2E2B777369004BAE8B /* UserCharts.swift */, @@ -69,8 +72,6 @@ 3E54FF0F2B772F1E00260FCB /* Assets.xcassets */, 3E54FF112B772F1E00260FCB /* iCUrHealth.entitlements */, 3E54FF122B772F1E00260FCB /* Preview Content */, - 3E54FF272B778BBB00260FCB /* HealthData.swift */, - 3E54FF292B778D9600260FCB /* DataAtAGlance.swift */, ); path = iCUrHealth; sourceTree = "<group>"; @@ -158,9 +159,12 @@ buildActionMask = 2147483647; files = ( 72C8BC312B77736E004BAE8B /* HealthChart.swift in Sources */, + 72C8BC352B77AEEE004BAE8B /* HealthData.swift in Sources */, + 72C8BC362B77AEEE004BAE8B /* DataAtAGlance.swift in Sources */, 3E54FF0E2B772F1C00260FCB /* ContentView.swift in Sources */, 3E54FF0C2B772F1C00260FCB /* iCUrHealthApp.swift in Sources */, 72C8BC2F2B777369004BAE8B /* UserCharts.swift in Sources */, + 72C8BC372B77AEEE004BAE8B /* DetailedAnalysisView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/iCUrHealth.xcodeproj/project.xcworkspace/xcuserdata/gsinnott.xcuserdatad/UserInterfaceState.xcuserstate b/iCUrHealth.xcodeproj/project.xcworkspace/xcuserdata/gsinnott.xcuserdatad/UserInterfaceState.xcuserstate Binary files differnew file mode 100644 index 0000000..bb5a5c6 --- /dev/null +++ b/iCUrHealth.xcodeproj/project.xcworkspace/xcuserdata/gsinnott.xcuserdatad/UserInterfaceState.xcuserstate diff --git a/iCUrHealth.xcodeproj/xcuserdata/gsinnott.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/iCUrHealth.xcodeproj/xcuserdata/gsinnott.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..52c474c --- /dev/null +++ b/iCUrHealth.xcodeproj/xcuserdata/gsinnott.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Bucket + uuid = "1A591F5C-3FB1-48CF-A772-55A5B3EF2A9D" + type = "1" + version = "2.0"> + <Breakpoints> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + uuid = "D59097E8-C62A-4608-84A0-55EBBAF85A69" + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "iCUrHealth/UserCharts.swift" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "53" + endingLineNumber = "53" + landmarkName = "body" + landmarkType = "24"> + <Locations> + <Location + uuid = "D59097E8-C62A-4608-84A0-55EBBAF85A69 - 74c810a07436c1bd" + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + symbolName = "closure #1 (iCUrHealth.HealthData) -> Swift.Optional<Charts.BarMark> in closure #1 () -> SwiftUI.ForEach<Swift.Array<iCUrHealth.HealthData>, Foundation.UUID, Swift.Optional<Charts.BarMark>> in closure #1 () -> <<opaque return type of SwiftUI.View.frame(width: Swift.Optional<CoreGraphics.CGFloat>, height: Swift.Optional<CoreGraphics.CGFloat>, alignment: SwiftUI.Alignment) -> some>>.0 in iCUrHealth.UserCharts.body.getter : some" + moduleName = "iCUrHealth" + usesParentBreakpointCondition = "Yes" + urlString = "file:///Users/gsinnott/Developer/iCUrHealth/iCUrHealth/UserCharts.swift" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "47" + endingLineNumber = "47" + offsetFromSymbolStart = "644"> + </Location> + <Location + uuid = "D59097E8-C62A-4608-84A0-55EBBAF85A69 - 8edbcb8dc24fe061" + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + symbolName = "closure #1 (iCUrHealth.HealthData) -> <<opaque return type of static Charts.ChartContentBuilder.buildPartialBlock<τ_0_0, τ_0_1 where τ_0_0: Charts.ChartContent, τ_0_1: Charts.ChartContent>(accumulated: τ_0_0, next: τ_0_1) -> some>>.0 in closure #1 () -> SwiftUI.ForEach<Swift.Array<iCUrHealth.HealthData>, Foundation.UUID, <<opaque return type of static Charts.ChartContentBuilder.buildPartialBlock<τ_0_0, τ_0_1 where τ_0_0: Charts.ChartContent, τ_0_1: Charts.ChartContent>(accumulated: τ_0_0, next: τ_0_1) -> some>>.0> in closure #1 () -> <<opaque return type of SwiftUI.View.frame(width: Swift.Optional<CoreGraphics.CGFloat>, height: Swift.Optional<CoreGraphics.CGFloat>, alignment: SwiftUI.Alignment) -> some>>.0 in iCUrHealth.UserCharts.body.getter : some" + moduleName = "iCUrHealth" + usesParentBreakpointCondition = "Yes" + urlString = "file:///Users/gsinnott/Developer/iCUrHealth/iCUrHealth/UserCharts.swift" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "35" + endingLineNumber = "35" + offsetFromSymbolStart = "1444"> + </Location> + <Location + uuid = "D59097E8-C62A-4608-84A0-55EBBAF85A69 - 128522ddb1d5f0a5" + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + symbolName = "closure #1 (iCUrHealth.HealthData) -> Swift.Optional<<<opaque return type of static Charts.ChartContentBuilder.buildPartialBlock<τ_0_0, τ_0_1 where τ_0_0: Charts.ChartContent, τ_0_1: Charts.ChartContent>(accumulated: τ_0_0, next: τ_0_1) -> some>>.0> in closure #1 () -> SwiftUI.ForEach<Swift.Array<iCUrHealth.HealthData>, Foundation.UUID, Swift.Optional<<<opaque return type of static Charts.ChartContentBuilder.buildPartialBlock<τ_0_0, τ_0_1 where τ_0_0: Charts.ChartContent, τ_0_1: Charts.ChartContent>(accumulated: τ_0_0, next: τ_0_1) -> some>>.0>> in closure #1 () -> SwiftUI.TupleView<(SwiftUI.Text, <<opaque return type of SwiftUI.View.frame(width: Swift.Optional<CoreGraphics.CGFloat>, height: Swift.Optional<CoreGraphics.CGFloat>, alignment: SwiftUI.Alignment) -> some>>.0, SwiftUI.Text, <<opaque return type of SwiftUI.View.frame(width: Swift.Optional<CoreGraphics.CGFloat>, height: Swift.Optional<CoreGraphics.CGFloat>, alignment: SwiftUI.Alignment) -> some>>.0)> in iCUrHealth.UserCharts.body.getter : some" + moduleName = "iCUrHealth" + usesParentBreakpointCondition = "Yes" + urlString = "file:///Users/gsinnott/Developer/iCUrHealth/iCUrHealth/UserCharts.swift" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "39" + endingLineNumber = "39" + offsetFromSymbolStart = "2592"> + </Location> + </Locations> + </BreakpointContent> + </BreakpointProxy> + <BreakpointProxy + BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> + <BreakpointContent + uuid = "E06021F5-9D1D-43C0-9BCB-9EE701FFA148" + shouldBeEnabled = "No" + ignoreCount = "0" + continueAfterRunningActions = "No" + filePath = "iCUrHealth/UserCharts.swift" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "54" + endingLineNumber = "54" + landmarkName = "body" + landmarkType = "24"> + <Locations> + <Location + uuid = "E06021F5-9D1D-43C0-9BCB-9EE701FFA148 - 74c810a07436c1bd" + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + symbolName = "closure #1 (iCUrHealth.HealthData) -> Swift.Optional<Charts.BarMark> in closure #1 () -> SwiftUI.ForEach<Swift.Array<iCUrHealth.HealthData>, Foundation.UUID, Swift.Optional<Charts.BarMark>> in closure #1 () -> <<opaque return type of SwiftUI.View.frame(width: Swift.Optional<CoreGraphics.CGFloat>, height: Swift.Optional<CoreGraphics.CGFloat>, alignment: SwiftUI.Alignment) -> some>>.0 in iCUrHealth.UserCharts.body.getter : some" + moduleName = "iCUrHealth" + usesParentBreakpointCondition = "Yes" + urlString = "file:///Users/gsinnott/Developer/iCUrHealth/iCUrHealth/UserCharts.swift" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "47" + endingLineNumber = "47" + offsetFromSymbolStart = "644"> + </Location> + <Location + uuid = "E06021F5-9D1D-43C0-9BCB-9EE701FFA148 - 8edbcb8dc24fe006" + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + symbolName = "closure #1 (iCUrHealth.HealthData) -> <<opaque return type of static Charts.ChartContentBuilder.buildPartialBlock<τ_0_0, τ_0_1 where τ_0_0: Charts.ChartContent, τ_0_1: Charts.ChartContent>(accumulated: τ_0_0, next: τ_0_1) -> some>>.0 in closure #1 () -> SwiftUI.ForEach<Swift.Array<iCUrHealth.HealthData>, Foundation.UUID, <<opaque return type of static Charts.ChartContentBuilder.buildPartialBlock<τ_0_0, τ_0_1 where τ_0_0: Charts.ChartContent, τ_0_1: Charts.ChartContent>(accumulated: τ_0_0, next: τ_0_1) -> some>>.0> in closure #1 () -> <<opaque return type of SwiftUI.View.frame(width: Swift.Optional<CoreGraphics.CGFloat>, height: Swift.Optional<CoreGraphics.CGFloat>, alignment: SwiftUI.Alignment) -> some>>.0 in iCUrHealth.UserCharts.body.getter : some" + moduleName = "iCUrHealth" + usesParentBreakpointCondition = "Yes" + urlString = "file:///Users/gsinnott/Developer/iCUrHealth/iCUrHealth/UserCharts.swift" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "36" + endingLineNumber = "36" + offsetFromSymbolStart = "1616"> + </Location> + <Location + uuid = "E06021F5-9D1D-43C0-9BCB-9EE701FFA148 - 94ee6a47e125ebaa" + shouldBeEnabled = "Yes" + ignoreCount = "0" + continueAfterRunningActions = "No" + symbolName = "closure #1 () -> <<opaque return type of SwiftUI.View.foregroundStyle<τ_0_0 where τ_1_0: SwiftUI.ShapeStyle>(τ_1_0) -> some>>.0 in closure #1 (iCUrHealth.HealthData) -> Swift.Optional<<<opaque return type of static Charts.ChartContentBuilder.buildPartialBlock<τ_0_0, τ_0_1 where τ_0_0: Charts.ChartContent, τ_0_1: Charts.ChartContent>(accumulated: τ_0_0, next: τ_0_1) -> some>>.0> in closure #1 () -> SwiftUI.ForEach<Swift.Array<iCUrHealth.HealthData>, Foundation.UUID, Swift.Optional<<<opaque return type of static Charts.ChartContentBuilder.buildPartialBlock<τ_0_0, τ_0_1 where τ_0_0: Charts.ChartContent, τ_0_1: Charts.ChartContent>(accumulated: τ_0_0, next: τ_0_1) -> some>>.0>> in closure #1 () -> SwiftUI.TupleView<(SwiftUI.Text, <<opaque return type of SwiftUI.View.frame(width: Swift.Optional<CoreGraphics.CGFloat>, height: Swift.Optional<CoreGraphics.CGFloat>, alignment: SwiftUI.Alignment) -> some>>.0, SwiftUI.Text, <<opaque return type of SwiftUI.View.frame(width: Swift.Optional<CoreGraphics.CGFloat>, height: Swift.Optional<CoreGraphics.CGFloat>, alignment: SwiftUI.Alignment) -> some>>.0)> in iCUrHealth.UserCharts.body.getter : some" + moduleName = "iCUrHealth" + usesParentBreakpointCondition = "Yes" + urlString = "file:///Users/gsinnott/Developer/iCUrHealth/iCUrHealth/UserCharts.swift" + startingColumnNumber = "9223372036854775807" + endingColumnNumber = "9223372036854775807" + startingLineNumber = "42" + endingLineNumber = "42" + offsetFromSymbolStart = "44"> + </Location> + </Locations> + </BreakpointContent> + </BreakpointProxy> + </Breakpoints> +</Bucket> diff --git a/iCUrHealth/ContentView.swift b/iCUrHealth/ContentView.swift index d544e09..812dd56 100644 --- a/iCUrHealth/ContentView.swift +++ b/iCUrHealth/ContentView.swift @@ -86,10 +86,7 @@ struct ContentView: View { Image(systemName: "gear") Text("Home") } - let ch1 = userChart(type: "bar", metric:"Steps", data: data) - let ch2 = userChart(type: "line", metric:"Steps", data: data) - let ch3 = userChart(type: "trend", metric:"Steps", data: data) - UserCharts(charts: [ch1]) + UserCharts() .tabItem { Image(systemName: "chart.xyaxis.line") Text("Charts") diff --git a/iCUrHealth/DataAtAGlance.swift b/iCUrHealth/DataAtAGlance.swift index f09ae3c..aef3315 100644 --- a/iCUrHealth/DataAtAGlance.swift +++ b/iCUrHealth/DataAtAGlance.swift @@ -74,7 +74,7 @@ struct DataAtAGlance: View { } } - var init_avg = initial_total / initial_count + var init_avg = max(initial_total / initial_count,1) var rece_avg = final_total / final_count var percentage = rece_avg*100/init_avg @@ -115,7 +115,7 @@ struct DataAtAGlance: View { } } - init_avg = initial_total / initial_count + init_avg = max(initial_total / initial_count,1) rece_avg = final_total / final_count percentage = rece_avg*100/init_avg diff --git a/iCUrHealth/UserCharts.swift b/iCUrHealth/UserCharts.swift index fe78dcd..c44b84c 100644 --- a/iCUrHealth/UserCharts.swift +++ b/iCUrHealth/UserCharts.swift @@ -6,6 +6,7 @@ // import SwiftUI +import Charts struct userChart: Identifiable { let type: String @@ -25,15 +26,65 @@ struct userChart: Identifiable { } +func getAverage(healthData: [HealthData]) -> Double { + var total = 0.0 + var count = 0.0 + for data in healthData { + if let stepCount = data.steps { + total += Double(stepCount) // Assuming stepCount is an Int + count += 1 + } + } + if count > 0 { + return total / count + } else { + return 0 // Return 0 to avoid division by zero if there are no step counts + } +} + struct UserCharts: View { - var charts: [userChart] + @State private var healthData: [HealthData] = [] var body: some View { VStack{ - ForEach(charts) { - chart in - VStack{ - HealthChart(chart: chart, average: chart.getTrend()) + Text("Step Count").font(.title) + Chart { + let average = getAverage(healthData: self.healthData) + ForEach(self.healthData) { data in + if let stepCount = data.steps { + BarMark(x: .value("Date", data.date), y: .value("Steps", stepCount)) + RuleMark(y: .value("Average", average)) + .foregroundStyle(Color.secondary) + .lineStyle(StrokeStyle(lineWidth: 0.8, dash: [10])) + .annotation(alignment: .bottomTrailing) { + Text(String(format: "Your average is: %.0f", average)) + .font(.subheadline).bold() + .padding(.trailing, 32) + .foregroundStyle(Color.secondary) + } + } + } + }.frame(height: 150) + Text("Active Energy").font(.title) + Chart { + ForEach(self.healthData) { data in + if let activeEnergy = data.activeEnergy { + BarMark(x: .value("Date", data.date), y: .value("Active Energy", activeEnergy)) + RuleMark(y: .value("Average", 10.0)) + .foregroundStyle(Color.secondary) + .lineStyle(StrokeStyle(lineWidth: 0.8, dash: [10])) + .annotation(alignment: .bottomTrailing) { + Text(String(format: "Your average is: %.0f", 10.0)) + .font(.subheadline).bold() + .padding(.trailing, 32) + .foregroundStyle(Color.secondary) + } + } } + }.frame(height: 250) + }.onAppear{ + let healthDataFetcher = HealthDataFetcher() + Task { + self.healthData = try await healthDataFetcher.fetchAndProcessHealthData() } } |