From d8903d685381e5f9c6e21aa50a64a3f2c54edd2e Mon Sep 17 00:00:00 2001 From: Paul Schmiedmayer Date: Fri, 10 Jan 2025 22:19:12 -0800 Subject: [PATCH] Update Release Notes and Re-Enable Periphery & CodeQL (#125) # Update Release Notes and Re-Enable Periphery & CodeQL ## :gear: Release Notes - Update Release Notes and Re-Enable Periphery ### Code of Conduct & Contributing Guidelines By submitting creating this pull request, you agree to follow our [Code of Conduct](https://github.com/StanfordBDHG/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordBDHG/.github/blob/main/CONTRIBUTING.md): - [x] I agree to follow the [Code of Conduct](https://github.com/StanfordBDHG/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordBDHG/.github/blob/main/CONTRIBUTING.md). --- .github/workflows/static-analysis.yml | 25 +++++++++++++----- .periphery.yml | 4 --- ENGAGEHF/ENGAGEHFStandard.swift | 9 +++---- ENGAGEHF/HeartHealth/HeartHealth.swift | 1 - .../SelectionTypes/GraphSelection.swift | 21 --------------- .../SelectionTypes/SymptomsType.swift | 4 --- .../SelectionTypes/VitalsType.swift | 4 --- .../VitalsGraph/DataTypes/SeriesTarget.swift | 2 -- .../Extensions/Double+Rounding.swift | 5 ---- .../Shared/VitalsGraph/VitalsGraph.swift | 4 +-- .../HKSampleGraph+ViewModel.swift | 4 +-- ENGAGEHF/HeartHealth/VitalsList.swift | 4 +-- ENGAGEHF/Managers/ManagerProtocol.swift | 1 + .../MedicationsManager.swift | 5 +--- .../Managers/MessageManager/Message.swift | 2 ++ .../MessageManager/MessageManager.swift | 6 ++--- .../NotificationManager.swift | 1 + .../Extensions/Decimal+IntConversion.swift | 6 ++--- .../FHIRObservation+GetEffectiveDate.swift | 2 +- .../Extensions/HKSample+GetDoubleValues.swift | 2 +- .../Managers/VitalsManager/SymptomScore.swift | 20 +++++++------- .../VitalsManager/VitalsManager.swift | 25 +++++++++--------- ENGAGEHF/Resources/Localizable.xcstrings | 2 +- .../StudyApplicationListCard.swift | 19 +++++++------- ENGAGEHF/SharedContext/FHIRAliases.swift | 4 --- ENGAGEHF/SharedContext/FeatureFlags.swift | 1 + .../SharedContext/Firebase+References.swift | 17 ------------ ENGAGEHF/SharedContext/StorageKeys.swift | 7 ----- fastlane/Fastfile | 26 +++++++++++++++---- fastlane/README.md | 22 +++++++++++++--- 30 files changed, 110 insertions(+), 145 deletions(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 3f644d9c..4a9b4fd6 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -28,15 +28,26 @@ jobs: uses: StanfordBDHG/.github/.github/workflows/swiftlint.yml@v2 permissions: contents: read - # periphery: - # name: Periphery - # uses: StanfordBDHG/.github/.github/workflows/periphery.yml@v2 - # permissions: - # contents: read - # with: - # runsonlabels: '["macOS", "self-hosted"]' + periphery: + name: Periphery + uses: StanfordBDHG/.github/.github/workflows/periphery.yml@v2 + permissions: + contents: read + with: + runsonlabels: '["macOS", "self-hosted"]' markdownlinkcheck: name: Markdown Link Check uses: StanfordBDHG/.github/.github/workflows/markdown-link-check.yml@v2 permissions: contents: read + # codeql: + # name: CodeQL + # uses: StanfordBDHG/.github/.github/workflows/xcodebuild-or-fastlane.yml@v2 + # permissions: + # security-events: write + # actions: read + # contents: read + # with: + # codeql: true + # fastlanelane: codeql + diff --git a/.periphery.yml b/.periphery.yml index 09784b73..aab7a4ae 100644 --- a/.periphery.yml +++ b/.periphery.yml @@ -9,7 +9,3 @@ project: ENGAGEHF.xcodeproj schemes: - ENGAGEHF -targets: -- ENGAGEHF -- ENGAGEHFTests -- ENGAGEHFUITests diff --git a/ENGAGEHF/ENGAGEHFStandard.swift b/ENGAGEHF/ENGAGEHFStandard.swift index 4d47136f..9140732d 100644 --- a/ENGAGEHF/ENGAGEHFStandard.swift +++ b/ENGAGEHF/ENGAGEHFStandard.swift @@ -23,12 +23,11 @@ import SwiftUI actor ENGAGEHFStandard: Standard, EnvironmentAccessible { - @Application(\.logger) private var logger - @Dependency(Account.self) private var account: Account? - @Dependency(FirebaseAccountService.self) private var accountService: FirebaseAccountService? - - + + @Application(\.logger) private var logger + + private var accountId: String { get async throws { guard let details = await account?.details else { diff --git a/ENGAGEHF/HeartHealth/HeartHealth.swift b/ENGAGEHF/HeartHealth/HeartHealth.swift index 415bafd5..2a407554 100644 --- a/ENGAGEHF/HeartHealth/HeartHealth.swift +++ b/ENGAGEHF/HeartHealth/HeartHealth.swift @@ -14,7 +14,6 @@ struct HeartHealth: View { @Binding var presentingAccount: Bool @Environment(NavigationManager.self) private var navigationManager - @Environment(VitalsManager.self) private var vitalsManager var body: some View { diff --git a/ENGAGEHF/HeartHealth/SelectionTypes/GraphSelection.swift b/ENGAGEHF/HeartHealth/SelectionTypes/GraphSelection.swift index 6c5cd4bc..33619c87 100644 --- a/ENGAGEHF/HeartHealth/SelectionTypes/GraphSelection.swift +++ b/ENGAGEHF/HeartHealth/SelectionTypes/GraphSelection.swift @@ -51,27 +51,6 @@ enum GraphSelection: CaseIterable, Identifiable, CustomStringConvertible, Equata } } - - init(collectionRef: CollectionReference?, for accountId: String) throws { - switch collectionRef { - case Firestore.symptomScoresCollectionReference(for: accountId): - self = .symptoms - case Firestore.collectionReference(for: accountId, type: HKQuantityType(.bodyMass)): - self = .weight - case Firestore.collectionReference(for: accountId, type: HKQuantityType(.heartRate)): - self = .heartRate - case Firestore.collectionReference(for: accountId, type: HKCorrelationType(.bloodPressure)): - self = .bloodPressure - default: - throw DecodingError.valueNotFound( - CollectionReference.self, - .init( - codingPath: [], - debugDescription: "No collection matches given reference." - ) - ) - } - } func collectionReference(for accountId: String) -> CollectionReference? { switch self { diff --git a/ENGAGEHF/HeartHealth/SelectionTypes/SymptomsType.swift b/ENGAGEHF/HeartHealth/SelectionTypes/SymptomsType.swift index 8f29d718..88466927 100644 --- a/ENGAGEHF/HeartHealth/SelectionTypes/SymptomsType.swift +++ b/ENGAGEHF/HeartHealth/SelectionTypes/SymptomsType.swift @@ -49,10 +49,6 @@ enum SymptomsType: String, CaseIterable, Identifiable, CustomStringConvertible, } } - var localizedEmptyHistoryWarning: String { - GraphSelection.symptoms.localizedEmptyHistoryWarning - } - /// The localized description of the symptoms score var localizedExplanation: String { switch self { diff --git a/ENGAGEHF/HeartHealth/SelectionTypes/VitalsType.swift b/ENGAGEHF/HeartHealth/SelectionTypes/VitalsType.swift index e4d1f940..49701df8 100644 --- a/ENGAGEHF/HeartHealth/SelectionTypes/VitalsType.swift +++ b/ENGAGEHF/HeartHealth/SelectionTypes/VitalsType.swift @@ -24,10 +24,6 @@ enum VitalsType: CustomStringConvertible { } } - var localizedEmptyHistoryWarning: String { - graphType.localizedEmptyHistoryWarning - } - /// The localized description of the vitals type var localizedExplanation: String { switch self { diff --git a/ENGAGEHF/HeartHealth/Shared/VitalsGraph/DataTypes/SeriesTarget.swift b/ENGAGEHF/HeartHealth/Shared/VitalsGraph/DataTypes/SeriesTarget.swift index 8378f97d..a09e633d 100644 --- a/ENGAGEHF/HeartHealth/Shared/VitalsGraph/DataTypes/SeriesTarget.swift +++ b/ENGAGEHF/HeartHealth/Shared/VitalsGraph/DataTypes/SeriesTarget.swift @@ -11,7 +11,5 @@ import Foundation struct SeriesTarget { let value: Double - let unit: String - let date: Date let label: String } diff --git a/ENGAGEHF/HeartHealth/Shared/VitalsGraph/Extensions/Double+Rounding.swift b/ENGAGEHF/HeartHealth/Shared/VitalsGraph/Extensions/Double+Rounding.swift index d94ec0a6..6d8e452a 100644 --- a/ENGAGEHF/HeartHealth/Shared/VitalsGraph/Extensions/Double+Rounding.swift +++ b/ENGAGEHF/HeartHealth/Shared/VitalsGraph/Extensions/Double+Rounding.swift @@ -23,9 +23,4 @@ extension Double { return target * (((self + offsetSign * offsetMagnitude) / target).rounded(rule)) } - - /// Rounds `self` to the nearest multiple of the given target, in the direction determedin by the given rule. - func roundedToNearestMultipleOf(_ target: Double, rule: FloatingPointRoundingRule = .up) -> Self { - self.roundedToNthMultipleOf(target, skipping: 0, rule: rule) - } } diff --git a/ENGAGEHF/HeartHealth/Shared/VitalsGraph/VitalsGraph.swift b/ENGAGEHF/HeartHealth/Shared/VitalsGraph/VitalsGraph.swift index 23c9de3e..7e3c5595 100644 --- a/ENGAGEHF/HeartHealth/Shared/VitalsGraph/VitalsGraph.swift +++ b/ENGAGEHF/HeartHealth/Shared/VitalsGraph/VitalsGraph.swift @@ -13,7 +13,6 @@ import SwiftUI struct VitalsGraph: View { let data: SeriesDictionary - let targetValue: SeriesTarget? let options: VitalsGraphOptions @State private var viewModel = ViewModel() @@ -35,9 +34,8 @@ struct VitalsGraph: View { } - init(data: SeriesDictionary, target: SeriesTarget? = nil, options: VitalsGraphOptions = .defaultOptions) { + init(data: SeriesDictionary, options: VitalsGraphOptions = .defaultOptions) { self.data = data - self.targetValue = target self.options = options } } diff --git a/ENGAGEHF/HeartHealth/Vitals/HKSampleGraph/HKSampleGraph+ViewModel.swift b/ENGAGEHF/HeartHealth/Vitals/HKSampleGraph/HKSampleGraph+ViewModel.swift index 5adda1a2..db9d1338 100644 --- a/ENGAGEHF/HeartHealth/Vitals/HKSampleGraph/HKSampleGraph+ViewModel.swift +++ b/ENGAGEHF/HeartHealth/Vitals/HKSampleGraph/HKSampleGraph+ViewModel.swift @@ -28,7 +28,7 @@ extension HKSampleGraph { return } - guard let (hkUnits, unitString) = getUnits(data: [target]) else { + guard let (hkUnits, _) = getUnits(data: [target]) else { self.targetValue = nil return } @@ -39,8 +39,6 @@ extension HKSampleGraph { case HKQuantityTypeIdentifier.bodyMass.rawValue: self.targetValue = SeriesTarget( value: quantitySample.quantity.doubleValue(for: hkUnits), - unit: unitString, - date: quantitySample.startDate, label: "Dry Weight" ) default: diff --git a/ENGAGEHF/HeartHealth/VitalsList.swift b/ENGAGEHF/HeartHealth/VitalsList.swift index 48068226..f3b508bb 100644 --- a/ENGAGEHF/HeartHealth/VitalsList.swift +++ b/ENGAGEHF/HeartHealth/VitalsList.swift @@ -10,9 +10,7 @@ import SwiftUI struct VitalsList: View { - @Environment(VitalsManager.self) private var vitalsManager - - var vitalSelection: GraphSelection + let vitalSelection: GraphSelection var body: some View { diff --git a/ENGAGEHF/Managers/ManagerProtocol.swift b/ENGAGEHF/Managers/ManagerProtocol.swift index 7ecdc805..f2c1df93 100644 --- a/ENGAGEHF/Managers/ManagerProtocol.swift +++ b/ENGAGEHF/Managers/ManagerProtocol.swift @@ -11,6 +11,7 @@ import Spezi /// A protocol to force refresh of the content of conforming Managers. protocol RefreshableContent { + // periphery:ignore - Actually used in the invitation code module. @MainActor func refreshContent() } diff --git a/ENGAGEHF/Managers/MedicationsManager/MedicationsManager.swift b/ENGAGEHF/Managers/MedicationsManager/MedicationsManager.swift index d3559bb6..6786b0dd 100644 --- a/ENGAGEHF/Managers/MedicationsManager/MedicationsManager.swift +++ b/ENGAGEHF/Managers/MedicationsManager/MedicationsManager.swift @@ -19,12 +19,9 @@ import SpeziFirebaseAccount @Observable @MainActor final class MedicationsManager: Manager { - @ObservationIgnored @StandardActor private var standard: ENGAGEHFStandard - @ObservationIgnored @Dependency(Account.self) private var account: Account? @ObservationIgnored @Dependency(AccountNotifications.self) private var accountNotifications: AccountNotifications? - @ObservationIgnored @Dependency(FirebaseAccountService.self) private var accountService: FirebaseAccountService? - + @Application(\.logger) @ObservationIgnored private var logger private var snapshotListener: ListenerRegistration? diff --git a/ENGAGEHF/Managers/MessageManager/Message.swift b/ENGAGEHF/Managers/MessageManager/Message.swift index 4b311825..bf647a91 100644 --- a/ENGAGEHF/Managers/MessageManager/Message.swift +++ b/ENGAGEHF/Managers/MessageManager/Message.swift @@ -19,7 +19,9 @@ struct Message: Identifiable, Equatable { let description: String? let action: MessageAction let isDismissible: Bool + // periphery:ignore - Currently not used in the app but a complete representation of the model. let dueDate: Date? + // periphery:ignore - Currently not used in the app but a complete representation of the model. let completionDate: Date? diff --git a/ENGAGEHF/Managers/MessageManager/MessageManager.swift b/ENGAGEHF/Managers/MessageManager/MessageManager.swift index aa75b13c..72c6b52b 100644 --- a/ENGAGEHF/Managers/MessageManager/MessageManager.swift +++ b/ENGAGEHF/Managers/MessageManager/MessageManager.swift @@ -22,12 +22,9 @@ import SpeziFirebaseAccount @Observable @MainActor final class MessageManager: Manager { - @ObservationIgnored @StandardActor var standard: ENGAGEHFStandard - @ObservationIgnored @Dependency(Account.self) private var account: Account? @ObservationIgnored @Dependency(AccountNotifications.self) private var accountNotifications: AccountNotifications? - @ObservationIgnored @Dependency(FirebaseAccountService.self) private var accountService: FirebaseAccountService? - + @Application(\.logger) @ObservationIgnored private var logger private(set) var messages: [Message] = [] @@ -167,6 +164,7 @@ final class MessageManager: Manager { #if DEBUG || TEST extension MessageManager { + // periphery:ignore - Used in Previews across the application. /// Adds a mock message to self.messages /// Used for testing in previews func addMockMessage(dismissible: Bool = true, action: MessageAction = .showHealthSummary) { diff --git a/ENGAGEHF/Managers/NotificationManager/NotificationManager.swift b/ENGAGEHF/Managers/NotificationManager/NotificationManager.swift index 55536fae..656f83d6 100644 --- a/ENGAGEHF/Managers/NotificationManager/NotificationManager.swift +++ b/ENGAGEHF/Managers/NotificationManager/NotificationManager.swift @@ -34,6 +34,7 @@ final class NotificationManager: Manager, NotificationHandler, NotificationToken @ObservationIgnored @Dependency(NavigationManager.self) private var navigationManager @ObservationIgnored @Dependency(Account.self) private var account: Account? + // periphery:ignore - Properly used then the TEST flag is not set. @ObservationIgnored @Application(\.registerRemoteNotifications) private var registerRemoteNotifications @ObservationIgnored @Application(\.logger) private var logger diff --git a/ENGAGEHF/Managers/VitalsManager/Extensions/Decimal+IntConversion.swift b/ENGAGEHF/Managers/VitalsManager/Extensions/Decimal+IntConversion.swift index 8fffbff8..c5b3c937 100644 --- a/ENGAGEHF/Managers/VitalsManager/Extensions/Decimal+IntConversion.swift +++ b/ENGAGEHF/Managers/VitalsManager/Extensions/Decimal+IntConversion.swift @@ -14,12 +14,12 @@ import Foundation /// Integer representation of the Decimal for use in creating Dates with time extension Decimal { /// Truncates the decimal and returns only the integer component as an Int - public var intValue: Int { + var intValue: Int { Int(truncating: self as NSNumber) } /// Removes the whole number and returns only the fractional component as an Int, truncated to a precision of 9 decimal places - public var fracValue: Int { + var fracValue: Int { NSDecimalNumber(decimal: self) .subtracting(NSDecimalNumber(value: self.intValue)) .multiplying(byPowerOf10: 9) @@ -31,7 +31,7 @@ extension Decimal { /// Conversion to Double extension Decimal { /// Returns a Double representation of the Decimal - public var doubleValue: Double { + var doubleValue: Double { NSDecimalNumber(decimal: self).doubleValue } } diff --git a/ENGAGEHF/Managers/VitalsManager/Extensions/FHIRObservation+GetEffectiveDate.swift b/ENGAGEHF/Managers/VitalsManager/Extensions/FHIRObservation+GetEffectiveDate.swift index ecf6d516..2237c11b 100644 --- a/ENGAGEHF/Managers/VitalsManager/Extensions/FHIRObservation+GetEffectiveDate.swift +++ b/ENGAGEHF/Managers/VitalsManager/Extensions/FHIRObservation+GetEffectiveDate.swift @@ -12,7 +12,7 @@ import ModelsR4 extension Observation { /// Returns Observation.effective as a startDate and an endDate, if present, converting from FHIR Primitives to Swift Dates - public func getEffectiveDate() -> (start: Date, end: Date)? { + func getEffectiveDate() -> (start: Date, end: Date)? { guard let effective else { return nil } diff --git a/ENGAGEHF/Managers/VitalsManager/Extensions/HKSample+GetDoubleValues.swift b/ENGAGEHF/Managers/VitalsManager/Extensions/HKSample+GetDoubleValues.swift index 2c4d252e..f3e1a53f 100644 --- a/ENGAGEHF/Managers/VitalsManager/Extensions/HKSample+GetDoubleValues.swift +++ b/ENGAGEHF/Managers/VitalsManager/Extensions/HKSample+GetDoubleValues.swift @@ -13,7 +13,7 @@ import HealthKit extension HKSample { /// Returns the Double value corresponding to each quantity in the Sample in the given units, if compatable /// For now, only supports HKQuantitySamples and HKCorrelations - public func getDoubleValues(for unit: HKUnit) -> [String: Double] { + func getDoubleValues(for unit: HKUnit) -> [String: Double] { switch self { case let quantitySample as HKQuantitySample: let quantity = quantitySample.quantity diff --git a/ENGAGEHF/Managers/VitalsManager/SymptomScore.swift b/ENGAGEHF/Managers/VitalsManager/SymptomScore.swift index abebc811..7097a7f2 100644 --- a/ENGAGEHF/Managers/VitalsManager/SymptomScore.swift +++ b/ENGAGEHF/Managers/VitalsManager/SymptomScore.swift @@ -13,20 +13,20 @@ import Foundation /// The score representing the result of a patient's response to a KCCQ survey /// Parameters are specified in compliance with: /// https://github.com/StanfordBDHG/ENGAGE-HF-Firebase/tree/web-data-scheme -public struct SymptomScore: Identifiable, Equatable { - @DocumentID public var id: String? - public let date: Date - public let overallScore: Double? - public let physicalLimitsScore: Double? - public let socialLimitsScore: Double? - public let qualityOfLifeScore: Double? - public let symptomFrequencyScore: Double? - public let dizzinessScore: Double? +struct SymptomScore: Identifiable, Equatable { + @DocumentID var id: String? + let date: Date + let overallScore: Double? + let physicalLimitsScore: Double? + let socialLimitsScore: Double? + let qualityOfLifeScore: Double? + let symptomFrequencyScore: Double? + let dizzinessScore: Double? } extension SymptomScore: Codable { - public init(from decoder: any Decoder) throws { + init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self._id = try container.decode(DocumentID.self, forKey: .id) diff --git a/ENGAGEHF/Managers/VitalsManager/VitalsManager.swift b/ENGAGEHF/Managers/VitalsManager/VitalsManager.swift index 9292a70d..2a9d487d 100644 --- a/ENGAGEHF/Managers/VitalsManager/VitalsManager.swift +++ b/ENGAGEHF/Managers/VitalsManager/VitalsManager.swift @@ -23,44 +23,43 @@ import SpeziFirestore /// - Convert FHIR observations to HKQuantitySamples and HKCorrelations @Observable @MainActor -public final class VitalsManager: Manager { +final class VitalsManager: Manager { @ObservationIgnored @StandardActor private var standard: ENGAGEHFStandard @ObservationIgnored @Dependency(Account.self) private var account: Account? @ObservationIgnored @Dependency(AccountNotifications.self) private var accountNotifications: AccountNotifications? - @ObservationIgnored @Dependency(FirebaseAccountService.self) private var accountService: FirebaseAccountService? - + @Application(\.logger) @ObservationIgnored private var logger private var snapshotListeners: [ListenerRegistration] = [] private var notificationsTask: Task? - public var heartRateHistory: [HKQuantitySample] = [] - public var bloodPressureHistory: [HKCorrelation] = [] - public var weightHistory: [HKQuantitySample] = [] + var heartRateHistory: [HKQuantitySample] = [] + var bloodPressureHistory: [HKCorrelation] = [] + var weightHistory: [HKQuantitySample] = [] - public var symptomHistory: [SymptomScore] = [] + var symptomHistory: [SymptomScore] = [] private(set) var latestDryWeight: HKQuantitySample? - public var latestHeartRate: HKQuantitySample? { + var latestHeartRate: HKQuantitySample? { heartRateHistory.max { $0.startDate < $1.startDate } } - public var latestBloodPressure: HKCorrelation? { + var latestBloodPressure: HKCorrelation? { bloodPressureHistory.max { $0.startDate < $1.startDate } } - public var latestWeight: HKQuantitySample? { + var latestWeight: HKQuantitySample? { weightHistory.max { $0.startDate < $1.startDate } } - nonisolated public init() {} + nonisolated init() {} /// Call on initial configuration: /// - Add a snapshot listener to the three health data collections - public func configure() { + func configure() { if ProcessInfo.processInfo.isPreviewSimulator { self.setupPreview() return @@ -94,7 +93,7 @@ public final class VitalsManager: Manager { } - public func refreshContent() { + func refreshContent() { updateSnapshotListener(for: account?.details) } diff --git a/ENGAGEHF/Resources/Localizable.xcstrings b/ENGAGEHF/Resources/Localizable.xcstrings index ff942469..a236e863 100644 --- a/ENGAGEHF/Resources/Localizable.xcstrings +++ b/ENGAGEHF/Resources/Localizable.xcstrings @@ -850,7 +850,7 @@ } } }, - "You are not in this medication, but it might be helpful in the future." : { + "You are not on this medication, but it might be helpful in the future." : { "comment" : "No action required legend entry." }, "You are on this medication, but may benefit from a higher dose." : { diff --git a/ENGAGEHF/ReusableElements/StudyApplicationListCard.swift b/ENGAGEHF/ReusableElements/StudyApplicationListCard.swift index 35f5e465..554a74a9 100644 --- a/ENGAGEHF/ReusableElements/StudyApplicationListCard.swift +++ b/ENGAGEHF/ReusableElements/StudyApplicationListCard.swift @@ -35,7 +35,16 @@ struct StudyApplicationListCard: View { } } +extension Text { + func studyApplicationHeaderStyle() -> some View { + self + .font(.title2.bold()) + .foregroundStyle(Color(.label)) + } +} + +#if DEBUG extension List { func studyApplicationList() -> some View { self @@ -49,16 +58,6 @@ extension List { } } -extension Text { - func studyApplicationHeaderStyle() -> some View { - self - .font(.title2.bold()) - .foregroundStyle(Color(.label)) - } -} - - -#if DEBUG #Preview("Sections") { NavigationStack { List { diff --git a/ENGAGEHF/SharedContext/FHIRAliases.swift b/ENGAGEHF/SharedContext/FHIRAliases.swift index c154d6e3..3fcab8b3 100644 --- a/ENGAGEHF/SharedContext/FHIRAliases.swift +++ b/ENGAGEHF/SharedContext/FHIRAliases.swift @@ -12,8 +12,4 @@ import ModelsR4 /// Type Aliases defined to avoid importing ModelsR4 into files that contain @Observable classes, which are broken by overlapping namespaces between ModelsR4 and the @Observable macro. typealias FHIRObservation = Observation -typealias FHIRCodableConcept = CodeableConcept -typealias FHIRMedication = Medication -typealias FHIRMedicationRequest = MedicationRequest -typealias FHIRReference = Reference typealias FHIRObservationComponent = ObservationComponent diff --git a/ENGAGEHF/SharedContext/FeatureFlags.swift b/ENGAGEHF/SharedContext/FeatureFlags.swift index a70325f4..8066414f 100644 --- a/ENGAGEHF/SharedContext/FeatureFlags.swift +++ b/ENGAGEHF/SharedContext/FeatureFlags.swift @@ -30,6 +30,7 @@ enum FeatureFlags { /// In the `UserMetaDataManager`, skips fetching user organization information and instead injects a test instance. /// No changes are made to the way notification settings are handled. static let setupTestUserMetaData = CommandLine.arguments.contains("--setupTestUserMetaData") + // periphery:ignore - Actually used in the Notification Manager /// Skips the call to `registerRemoteNotifications` in the `NotificationManager`, and uses an empty token instead. static let skipRemoteNotificationRegistration = CommandLine.arguments.contains("--skipRemoteNotificationRegistration") #if targetEnvironment(simulator) diff --git a/ENGAGEHF/SharedContext/Firebase+References.swift b/ENGAGEHF/SharedContext/Firebase+References.swift index 1f473bde..7083d366 100644 --- a/ENGAGEHF/SharedContext/Firebase+References.swift +++ b/ENGAGEHF/SharedContext/Firebase+References.swift @@ -65,17 +65,6 @@ extension Firestore { static func questionnaireResponseCollectionReference(for accountId: String) -> CollectionReference { userDocumentReference(for: accountId).collection("questionnaireResponses") } - - static func heartHealthCollectionReferences(for accountId: String) -> [CollectionReference] { - [ - symptomScoresCollectionReference(for: accountId), - collectionReference(for: accountId, type: HKQuantityType(.bodyMass)), - collectionReference(for: accountId, type: HKQuantityType(.heartRate)), - collectionReference(for: accountId, type: HKCorrelationType(.bloodPressure)) - ] - .compactMap { $0 } - } - static func collectionReference(for accountId: String, type: HKSampleType) -> CollectionReference? { switch type { @@ -94,9 +83,3 @@ extension Firestore { } } } - -extension Storage { - static func userBucketReference(for accountId: String) -> StorageReference { - Storage.storage().reference().child("users/\(accountId)") - } -} diff --git a/ENGAGEHF/SharedContext/StorageKeys.swift b/ENGAGEHF/SharedContext/StorageKeys.swift index 83e48b4f..cd4db1e8 100644 --- a/ENGAGEHF/SharedContext/StorageKeys.swift +++ b/ENGAGEHF/SharedContext/StorageKeys.swift @@ -11,11 +11,4 @@ enum StorageKeys { // MARK: - Onboarding /// A `Bool` flag indicating of the onboarding was completed. static let onboardingFlowComplete = "onboardingFlow.complete" - /// A `Step` flag indicating the current step in the onboarding process. - static let onboardingFlowStep = "onboardingFlow.step" - - - // MARK: - Home - /// The currently selected home tab. - static let homeTabSelection = "home.tabselection" } diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 3774c3b4..a139f3b9 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -13,7 +13,9 @@ APP_CONFIG = { default_app_identifier: "edu.stanford.bdh.engagehf", default_provisioningProfile: "Stanford BDHG ENGAGE-HF", default_version_name: "2.0.1", - default_release_notes: "Bug fixes and performance improvements." + default_release_notes: "Bug fixes and performance improvements.", + scheme: "ENGAGEHF", + plist_path: "ENGAGEHF/Supporting Files/Info.plist" }.freeze platform :ios do @@ -64,7 +66,7 @@ platform :ios do languages: [ "en-US", ], - scheme: "ENGAGEHF", + scheme: APP_CONFIG[:scheme], output_directory: "./fastlane/screenshots", clear_previous_screenshots: true, concurrent_simulators: false, @@ -78,6 +80,20 @@ platform :ios do end end + desc "CodeQL" + lane :codeql do + ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "320" # CodeQL runs on GitHub CI. We need much higher timeout here. + build_app( + skip_archive: true, + skip_codesigning: true, + derived_data_path: ".derivedData", + xcargs: [ + "-skipPackagePluginValidation", + "-skipMacroValidation" + ] + ) + end + desc "Build app" lane :build do build_app( @@ -97,7 +113,7 @@ platform :ios do provisioningProfile = options[:provisioningProfile].to_s.strip.empty? ? APP_CONFIG[:default_provisioningProfile] : options[:provisioningProfile] update_app_identifier( - plist_path: "ENGAGEHF/Supporting Files/Info.plist", + plist_path: APP_CONFIG[:plist_path], app_identifier: appidentifier ) @@ -161,9 +177,9 @@ platform :ios do if environment == "production" deliver( app_identifier: appidentifier, - release_notes: ({ + release_notes: { 'default' => releasenotes - }), + }, submit_for_review: true, force: true, reject_if_possible: true, diff --git a/fastlane/README.md b/fastlane/README.md index 140582f7..ea425cb8 100644 --- a/fastlane/README.md +++ b/fastlane/README.md @@ -23,6 +23,14 @@ For _fastlane_ installation instructions, see [Installing _fastlane_](https://do Build and test +### ios screenshots + +```sh +[bundle exec] fastlane ios screenshots +``` + +Screenshots + ### ios codeql ```sh @@ -39,6 +47,14 @@ CodeQL Build app +### ios archive + +```sh +[bundle exec] fastlane ios archive +``` + +Archive app + ### ios signin ```sh @@ -47,13 +63,13 @@ Build app Sign in to the App Store Connect API -### ios beta +### ios deploy ```sh -[bundle exec] fastlane ios beta +[bundle exec] fastlane ios deploy ``` -Publish a beta release to internal TestFlight testers +Publish a release to TestFlight or the App Store depending on the environment ----