Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions OCKSample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
701230EA280DE687003F5ECE /* OCKAnyEvent+Answer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 701230E9280DE687003F5ECE /* OCKAnyEvent+Answer.swift */; };
701230EB280DE687003F5ECE /* OCKAnyEvent+Answer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 701230E9280DE687003F5ECE /* OCKAnyEvent+Answer.swift */; };
701230F12810894D003F5ECE /* CustomContactViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 701230F02810894D003F5ECE /* CustomContactViewController.swift */; };
7012312428146365003F5ECE /* InsightsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7012312328146365003F5ECE /* InsightsViewController.swift */; };
701231262814638E003F5ECE /* InsightsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 701231252814638E003F5ECE /* InsightsView.swift */; };
70123128281463A2003F5ECE /* InsightsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70123127281463A2003F5ECE /* InsightsViewModel.swift */; };
70202EC12807333900CF73FB /* CareKit in Frameworks */ = {isa = PBXBuildFile; productRef = 70202EC02807333900CF73FB /* CareKit */; };
70202EC32807333900CF73FB /* CareKitFHIR in Frameworks */ = {isa = PBXBuildFile; productRef = 70202EC22807333900CF73FB /* CareKitFHIR */; };
70202EC52807333A00CF73FB /* CareKitUI in Frameworks */ = {isa = PBXBuildFile; productRef = 70202EC42807333A00CF73FB /* CareKitUI */; };
Expand Down Expand Up @@ -201,6 +204,9 @@
701230E7280DE595003F5ECE /* SurveyViewSynchronizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SurveyViewSynchronizer.swift; sourceTree = "<group>"; };
701230E9280DE687003F5ECE /* OCKAnyEvent+Answer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OCKAnyEvent+Answer.swift"; sourceTree = "<group>"; };
701230F02810894D003F5ECE /* CustomContactViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomContactViewController.swift; sourceTree = "<group>"; };
7012312328146365003F5ECE /* InsightsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InsightsViewController.swift; sourceTree = "<group>"; };
701231252814638E003F5ECE /* InsightsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InsightsView.swift; sourceTree = "<group>"; };
70123127281463A2003F5ECE /* InsightsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InsightsViewModel.swift; sourceTree = "<group>"; };
70202EC9280746E900CF73FB /* ResearchKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ResearchKit.xcodeproj; path = ResearchKit/ResearchKit.xcodeproj; sourceTree = "<group>"; };
70202ED52807529900CF73FB /* Surveys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Surveys.swift; sourceTree = "<group>"; };
70308885258273D400FFABB6 /* LoginViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModel.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -343,6 +349,16 @@
path = Cards;
sourceTree = "<group>";
};
7012311F28146340003F5ECE /* Insights */ = {
isa = PBXGroup;
children = (
701231252814638E003F5ECE /* InsightsView.swift */,
7012312328146365003F5ECE /* InsightsViewController.swift */,
70123127281463A2003F5ECE /* InsightsViewModel.swift */,
);
path = Insights;
sourceTree = "<group>";
};
70202ECA280746E900CF73FB /* Products */ = {
isa = PBXGroup;
children = (
Expand All @@ -355,6 +371,7 @@
703088772582727500FFABB6 /* MainTabs */ = {
isa = PBXGroup;
children = (
7012311F28146340003F5ECE /* Insights */,
91693819271B64CB00A634ED /* Stylers */,
70308878258272CD00FFABB6 /* Care */,
7036E4D2256EBE35006E9A3C /* MainView.swift */,
Expand Down Expand Up @@ -888,6 +905,7 @@
7036E64025717F85006E9A3C /* Constants.swift in Sources */,
918FDEBC271B4E4A0045A0EF /* Calendar+Dates.swift in Sources */,
70F03AA127860AB700E5AFB4 /* OCKOutcome+default.swift in Sources */,
70123128281463A2003F5ECE /* InsightsViewModel.swift in Sources */,
7036E4CE256E9A0C006E9A3C /* ContactView.swift in Sources */,
70F03A972786098F00E5AFB4 /* OCKStore+Default.swift in Sources */,
70DFD80B2567074500B9DB12 /* LoginView.swift in Sources */,
Expand All @@ -900,6 +918,8 @@
9169381D271B650700A634ED /* ColorStyle.swift in Sources */,
E72B2C0A226939E3009A9438 /* AppDelegate.swift in Sources */,
7036E4C4256E0A48006E9A3C /* CareView.swift in Sources */,
7012312428146365003F5ECE /* InsightsViewController.swift in Sources */,
701231262814638E003F5ECE /* InsightsView.swift in Sources */,
70F921B027CABED600368CEC /* LocalSyncSessionDelegate.swift in Sources */,
70123069280830A1003F5ECE /* Consent.swift in Sources */,
70F03A932786087800E5AFB4 /* OCKAnyEvent+CustomStringConvertable.swift in Sources */,
Expand Down
19 changes: 19 additions & 0 deletions OCKSample/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Foundation
import CareKit
import CareKitStore
import ParseSwift
import os.log

enum AppError: Error {
case couldntCast
Expand Down Expand Up @@ -98,3 +99,21 @@ enum UserType: String, Codable {
enum InstallationChannel: String {
case global
}

let eventAggregatorMean = OCKEventAggregator.custom { events -> Double in

let totalCompleted = Double(events.map { $0.outcome?.values.count ?? 0 }.reduce(0, +))

Logger.constants.debug("Total \(totalCompleted)")

let tempSumOfCompleted = events.compactMap { $0.outcome?.values.compactMap { $0.doubleValue ?? 0.0 }.reduce(0, +) }
Logger.constants.debug("TempSum \(tempSumOfCompleted)")
let sumOfCompleted = Double(tempSumOfCompleted.compactMap { $0 }.reduce(0, +))
Logger.constants.debug("Sum \(sumOfCompleted)")

if totalCompleted == 0 {
return Double(0)
} else {
return sumOfCompleted / totalCompleted
}
}
1 change: 1 addition & 0 deletions OCKSample/Extensions/Logger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ extension Logger {
static let ockStore = Logger(subsystem: subsystem, category: "OCKStore+Extension")
static let ockHealthKitPassthroughStore = Logger(subsystem: subsystem,
category: "OCKHealthKitPassthroughStore+Extension")
static let constants = Logger(subsystem: subsystem, category: "Constants")
}
37 changes: 0 additions & 37 deletions OCKSample/MainTabs/Care/CareViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ import CareKitUI
import ResearchKit
import os.log

// swiftlint:disable type_body_length

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably won't need to remove this line in your apps.


class CareViewController: OCKDailyPageViewController {

private var isSyncing = false
Expand Down Expand Up @@ -278,41 +276,6 @@ class CareViewController: OCKDailyPageViewController {

case TaskID.nausea:
var cards = [UIViewController]()
// dynamic gradient colors
let nauseaGradientStart = UIColor { traitCollection -> UIColor in
return traitCollection.userInterfaceStyle == .light ? #colorLiteral(red: 0.06253327429, green: 0.6597633362, blue: 0.8644603491, alpha: 1) : #colorLiteral(red: 0, green: 0.2858072221, blue: 0.6897063851, alpha: 1)
}
let nauseaGradientEnd = UIColor { traitCollection -> UIColor in
return traitCollection.userInterfaceStyle == .light ? #colorLiteral(red: 0, green: 0.2858072221, blue: 0.6897063851, alpha: 1) : #colorLiteral(red: 0.06253327429, green: 0.6597633362, blue: 0.8644603491, alpha: 1)
}

// Create a plot comparing nausea to medication adherence.
let nauseaDataSeries = OCKDataSeriesConfiguration(
taskID: "nausea",
legendTitle: "Nausea",
gradientStartColor: nauseaGradientStart,
gradientEndColor: nauseaGradientEnd,
markerSize: 10,
eventAggregator: OCKEventAggregator.countOutcomeValues)

let doxylamineDataSeries = OCKDataSeriesConfiguration(
taskID: "doxylamine",
legendTitle: "Doxylamine",
gradientStartColor: .systemGray2,
gradientEndColor: .systemGray,
markerSize: 10,
eventAggregator: OCKEventAggregator.countOutcomeValues)

let insightsCard = OCKCartesianChartViewController(
plotType: .bar,
selectedDate: date,
configurations: [nauseaDataSeries, doxylamineDataSeries],
storeManager: self.storeManager)

insightsCard.chartView.headerView.titleLabel.text = "Nausea & Doxylamine Intake"
insightsCard.chartView.headerView.detailLabel.text = "This Week"
insightsCard.chartView.headerView.accessibilityLabel = "Nausea & Doxylamine Intake, This Week"
cards.append(insightsCard)

// Also create a card that displays a single event.
// The event query passed into the initializer specifies that only
Expand Down
66 changes: 66 additions & 0 deletions OCKSample/MainTabs/Insights/InsightsView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//
// InsightsView.swift
// OCKSample
//
// Created by Corey Baker on 4/23/22.
// Copyright © 2022 Network Reconnaissance Lab. All rights reserved.
//

/*
You should notice this looks like CareView but with references
to InsightsViewController instead.
*/

import SwiftUI
import UIKit
import CareKit
import CareKitStore
import os.log

struct InsightsView: UIViewControllerRepresentable {

@ObservedObject var viewModel = InsightsViewModel()

@MainActor
func makeUIViewController(context: Context) -> some UIViewController {
let viewController = createViewContoller()
let navigationController = UINavigationController(rootViewController: viewController)
navigationController.navigationBar.backgroundColor = UIColor { $0.userInterfaceStyle == .light ? #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1): #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1) }

return navigationController
}

@MainActor
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
// swiftlint:disable:next force_cast
let appDelegate = UIApplication.shared.delegate as! AppDelegate

if appDelegate.isFirstLogin && appDelegate.isFirstAppOpen {
guard let navigationController = uiViewController as? UINavigationController,
let currentViewController = navigationController.viewControllers.first as? InsightsViewController,
appDelegate.storeManager !== currentViewController.storeManager else {
return
}
// Replace current view controller
let viewController = createViewContoller()
navigationController.viewControllers = [viewController]
}
}

// MARK: Helpers
func createViewContoller() -> UIViewController {
guard let manager = StoreManagerKey.defaultValue else {
Logger.insights.error("Couldn't unwrap storeManager")
return InsightsViewController(storeManager: .init(wrapping: OCKStore(name: "none_insights",
type: .inMemory)))
}
return InsightsViewController(storeManager: manager)
}
}

struct InsightsView_Previews: PreviewProvider {

static var previews: some View {
InsightsView()
}
}
Loading