From 86c467329a1d50656b026877d6daacf088d5460f Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Thu, 8 Jun 2023 15:06:14 +0200 Subject: [PATCH 01/13] Remove deprecated swiftlint warnings --- .swiftlint.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 4ef956c..ef0fa05 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -141,8 +141,6 @@ only_rules: - implicitly_unwrapped_optional # Identifiers should use inclusive language that avoids discrimination against groups of people based on race, gender, or socioeconomic status - inclusive_language - # If defer is at the end of its parent scope, it will be executed right where it is anyway. - - inert_defer # Prefer using Set.isDisjoint(with:) over Set.intersection(_:).isEmpty. - is_disjoint # Discouraged explicit usage of the default separator. @@ -331,8 +329,6 @@ only_rules: - unowned_variable_capture # Catch statements should not declare error variables without type casting. - untyped_error_in_catch - # Unused reference in a capture list should be removed. - - unused_capture_list # Unused parameter in a closure should be replaced with _. - unused_closure_parameter # Unused control flow label should be removed. From f10ed6ded6af317a95a2f1b374a90b434caea041 Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Thu, 8 Jun 2023 15:07:25 +0200 Subject: [PATCH 02/13] Fix some swiftlint warnings --- NAMS.xcodeproj/xcshareddata/xcschemes/NAMS.xcscheme | 4 ++++ NAMS/Home.swift | 5 ++--- NAMS/NAMS.swift | 7 ++++--- NAMS/NAMSTestingSetup.swift | 4 ++-- NAMS/Onboarding/AccountSetup/AccountSetup.swift | 6 +++--- NAMS/Onboarding/AccountSetup/IconView.swift | 1 - NAMS/Onboarding/AccountSetup/UserView.swift | 3 +-- NAMS/Onboarding/HealthKitPermissions.swift | 3 ++- NAMS/Onboarding/OnboardingFlow.swift | 6 ++++-- NAMS/Schedule/ScheduleView.swift | 3 ++- 10 files changed, 24 insertions(+), 18 deletions(-) diff --git a/NAMS.xcodeproj/xcshareddata/xcschemes/NAMS.xcscheme b/NAMS.xcodeproj/xcshareddata/xcschemes/NAMS.xcscheme index 7b5578f..c21f007 100644 --- a/NAMS.xcodeproj/xcshareddata/xcschemes/NAMS.xcscheme +++ b/NAMS.xcodeproj/xcshareddata/xcschemes/NAMS.xcscheme @@ -94,6 +94,10 @@ isEnabled = "NO"> + + some View { content diff --git a/NAMS/Onboarding/AccountSetup/AccountSetup.swift b/NAMS/Onboarding/AccountSetup/AccountSetup.swift index fb88c2c..c151fed 100644 --- a/NAMS/Onboarding/AccountSetup/AccountSetup.swift +++ b/NAMS/Onboarding/AccountSetup/AccountSetup.swift @@ -55,7 +55,7 @@ struct AccountSetup: View { } @ViewBuilder - private var accountImage: some View { + private var accountImage: some View { // swiftlint:disable:this attributes Group { if account.signedIn { Image(systemName: "person.badge.shield.checkmark.fill") @@ -68,7 +68,7 @@ struct AccountSetup: View { } @ViewBuilder - private var accountDescription: some View { + private var accountDescription: some View { // swiftlint:disable:this attributes VStack { Group { if account.signedIn { @@ -90,7 +90,7 @@ struct AccountSetup: View { } @ViewBuilder - private var actionView: some View { + private var actionView: some View { // swiftlint:disable:this attributes if account.signedIn { OnboardingActionsView( "ACCOUNT_NEXT".moduleLocalized, diff --git a/NAMS/Onboarding/AccountSetup/IconView.swift b/NAMS/Onboarding/AccountSetup/IconView.swift index 1898d1a..4d3ec72 100644 --- a/NAMS/Onboarding/AccountSetup/IconView.swift +++ b/NAMS/Onboarding/AccountSetup/IconView.swift @@ -12,7 +12,6 @@ import SwiftUI struct IconView: View { let size: Double - var body: some View { Image(uiImage: Bundle.main.image(withName: "AppIcon", fileExtension: "png")) .resizable() diff --git a/NAMS/Onboarding/AccountSetup/UserView.swift b/NAMS/Onboarding/AccountSetup/UserView.swift index 108f9d4..1461a36 100644 --- a/NAMS/Onboarding/AccountSetup/UserView.swift +++ b/NAMS/Onboarding/AccountSetup/UserView.swift @@ -29,9 +29,8 @@ struct UserView: View { ) } - @ViewBuilder - private var userInformation: some View { + private var userInformation: some View { // swiftlint:disable:this attributes HStack(spacing: 16) { if account.signedIn, let user = firebaseAccountConfiguration.user, diff --git a/NAMS/Onboarding/HealthKitPermissions.swift b/NAMS/Onboarding/HealthKitPermissions.swift index fafe4c9..226d199 100644 --- a/NAMS/Onboarding/HealthKitPermissions.swift +++ b/NAMS/Onboarding/HealthKitPermissions.swift @@ -14,7 +14,8 @@ import SwiftUI struct HealthKitPermissions: View { @EnvironmentObject var healthKitDataSource: HealthKit - @AppStorage(StorageKeys.onboardingFlowComplete) var completedOnboardingFlow = false + @AppStorage(StorageKeys.onboardingFlowComplete) + var completedOnboardingFlow = false @State var healthKitProcessing = false diff --git a/NAMS/Onboarding/OnboardingFlow.swift b/NAMS/Onboarding/OnboardingFlow.swift index d4f7f94..88affc2 100644 --- a/NAMS/Onboarding/OnboardingFlow.swift +++ b/NAMS/Onboarding/OnboardingFlow.swift @@ -20,8 +20,10 @@ struct OnboardingFlow: View { case healthKitPermissions } - @SceneStorage(StorageKeys.onboardingFlowStep) private var onboardingSteps: [Step] = [] - @AppStorage(StorageKeys.onboardingFlowComplete) var completedOnboardingFlow = false + @SceneStorage(StorageKeys.onboardingFlowStep) + private var onboardingSteps: [Step] = [] + @AppStorage(StorageKeys.onboardingFlowComplete) + var completedOnboardingFlow = false var body: some View { diff --git a/NAMS/Schedule/ScheduleView.swift b/NAMS/Schedule/ScheduleView.swift index 4f6f49c..6327391 100644 --- a/NAMS/Schedule/ScheduleView.swift +++ b/NAMS/Schedule/ScheduleView.swift @@ -53,7 +53,7 @@ struct ScheduleView: View { private func destination(withContext eventContext: EventContext) -> some View { @ViewBuilder - var destination: some View { + var destination: some View { // swiftlint:disable:this attributes switch eventContext.task.context { case let .questionnaire(questionnaire): QuestionnaireView(questionnaire: questionnaire) { _ in @@ -63,6 +63,7 @@ struct ScheduleView: View { } } } + return destination } From 3f8e19e186521c44f28a2880037f2b703e02e5f3 Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Sun, 11 Jun 2023 18:37:20 +0200 Subject: [PATCH 03/13] Initial restructuring of the onboarding flow --- NAMS.xcodeproj/project.pbxproj | 12 +++-- .../CodableArray+RawRepresentable.swift | 1 + NAMS/{NAMS.swift => NAMSApp.swift} | 4 +- NAMS/NAMSAppDelegate.swift | 2 +- .../AccountSetup/AccountSetup.swift | 16 +++--- NAMS/Onboarding/AccountSetup/NAMSLogin.swift | 6 ++- NAMS/Onboarding/AccountSetup/NAMSSignUp.swift | 6 ++- NAMS/Onboarding/Consent.swift | 2 +- NAMS/Onboarding/FinishedSetup.swift | 51 +++++++++++++++++++ NAMS/Onboarding/InterestingModules.swift | 5 ++ NAMS/Onboarding/OnboardingFlow.swift | 13 ++--- NAMS/Onboarding/Welcome.swift | 10 ++-- NAMS/Resources/Localizable.strings | 25 +++++---- NAMS/Schedule/NAMSTaskContext.swift | 2 +- NAMS/SharedContext/FeatureFlags.swift | 2 +- 15 files changed, 111 insertions(+), 46 deletions(-) rename NAMS/{NAMS.swift => NAMSApp.swift} (91%) create mode 100644 NAMS/Onboarding/FinishedSetup.swift diff --git a/NAMS.xcodeproj/project.pbxproj b/NAMS.xcodeproj/project.pbxproj index 63c49f0..7e61cf1 100644 --- a/NAMS.xcodeproj/project.pbxproj +++ b/NAMS.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 2DC17337BA4FEF5664BC0D10 /* FinishedSetup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DC173772F6FD3C05EBFCE52 /* FinishedSetup.swift */; }; 2F49B7762980407C00BCB272 /* Spezi in Frameworks */ = {isa = PBXBuildFile; productRef = 2F49B7752980407B00BCB272 /* Spezi */; }; 2F4E237E2989A2FE0013F3D9 /* OnboardingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4E237D2989A2FE0013F3D9 /* OnboardingTests.swift */; }; 2F4E23832989D51F0013F3D9 /* NAMSTestingSetup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4E23822989D51F0013F3D9 /* NAMSTestingSetup.swift */; }; @@ -62,7 +63,7 @@ 2FE5DCB029EE6107004B9AB4 /* UserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DCAB29EE6107004B9AB4 /* UserView.swift */; }; 2FE5DCB129EE6107004B9AB4 /* AccountSetup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DCAC29EE6107004B9AB4 /* AccountSetup.swift */; }; 2FE5DCB229EE6107004B9AB4 /* NAMSLogin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DCAD29EE6107004B9AB4 /* NAMSLogin.swift */; }; - 653A2551283387FE005D4D48 /* NAMS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653A2550283387FE005D4D48 /* NAMS.swift */; }; + 653A2551283387FE005D4D48 /* NAMSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653A2550283387FE005D4D48 /* NAMSApp.swift */; }; 653A255528338800005D4D48 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 653A255428338800005D4D48 /* Assets.xcassets */; }; 653A256228338800005D4D48 /* NAMSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653A256128338800005D4D48 /* NAMSTests.swift */; }; 653A256C28338800005D4D48 /* SchedulerAndQuestionnaireTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 653A256B28338800005D4D48 /* SchedulerAndQuestionnaireTests.swift */; }; @@ -86,6 +87,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 2DC173772F6FD3C05EBFCE52 /* FinishedSetup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FinishedSetup.swift; sourceTree = ""; }; 2F4E237D2989A2FE0013F3D9 /* OnboardingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingTests.swift; sourceTree = ""; }; 2F4E23822989D51F0013F3D9 /* NAMSTestingSetup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NAMSTestingSetup.swift; sourceTree = ""; }; 2F4E23862989DB360013F3D9 /* ContactsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactsTests.swift; sourceTree = ""; }; @@ -124,7 +126,7 @@ 2FE5DCAC29EE6107004B9AB4 /* AccountSetup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountSetup.swift; sourceTree = ""; }; 2FE5DCAD29EE6107004B9AB4 /* NAMSLogin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NAMSLogin.swift; sourceTree = ""; }; 653A254D283387FE005D4D48 /* NAMS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NAMS.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 653A2550283387FE005D4D48 /* NAMS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NAMS.swift; sourceTree = ""; }; + 653A2550283387FE005D4D48 /* NAMSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NAMSApp.swift; sourceTree = ""; }; 653A255428338800005D4D48 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 653A255D28338800005D4D48 /* NAMSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NAMSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 653A256128338800005D4D48 /* NAMSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NAMSTests.swift; sourceTree = ""; }; @@ -214,6 +216,7 @@ 2FE5DC3129EDD7CA004B9AB4 /* OnboardingFlow.swift */, 2FE5DC3329EDD7CA004B9AB4 /* String+ModuleLocalized.swift */, 2FE5DC3429EDD7CA004B9AB4 /* Welcome.swift */, + 2DC173772F6FD3C05EBFCE52 /* FinishedSetup.swift */, ); path = Onboarding; sourceTree = ""; @@ -299,7 +302,7 @@ 653A254F283387FE005D4D48 /* NAMS */ = { isa = PBXGroup; children = ( - 653A2550283387FE005D4D48 /* NAMS.swift */, + 653A2550283387FE005D4D48 /* NAMSApp.swift */, 2F5E32BC297E05EA003432F8 /* NAMSAppDelegate.swift */, 2F4E23822989D51F0013F3D9 /* NAMSTestingSetup.swift */, 2FC975A72978F11A00BA99FE /* Home.swift */, @@ -564,9 +567,10 @@ 2FE5DC5129EDD7FA004B9AB4 /* NAMSTaskContext.swift in Sources */, 2F5E32BD297E05EA003432F8 /* NAMSAppDelegate.swift in Sources */, 2FE5DC5229EDD7FA004B9AB4 /* NAMSScheduler.swift in Sources */, - 653A2551283387FE005D4D48 /* NAMS.swift in Sources */, + 653A2551283387FE005D4D48 /* NAMSApp.swift in Sources */, 2FE5DC3629EDD7CA004B9AB4 /* HealthKitPermissions.swift in Sources */, 2FE5DC2629EDD38A004B9AB4 /* Contacts.swift in Sources */, + 2DC17337BA4FEF5664BC0D10 /* FinishedSetup.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/NAMS/Helper/CodableArray+RawRepresentable.swift b/NAMS/Helper/CodableArray+RawRepresentable.swift index c8eeeff..9973603 100644 --- a/NAMS/Helper/CodableArray+RawRepresentable.swift +++ b/NAMS/Helper/CodableArray+RawRepresentable.swift @@ -9,6 +9,7 @@ import Foundation +// TODO why is this used forcing JSON? extension Array: RawRepresentable where Element: Codable { public var rawValue: String { guard let data = try? JSONEncoder().encode(self), diff --git a/NAMS/NAMS.swift b/NAMS/NAMSApp.swift similarity index 91% rename from NAMS/NAMS.swift rename to NAMS/NAMSApp.swift index 7f19b62..86b26ce 100644 --- a/NAMS/NAMS.swift +++ b/NAMS/NAMSApp.swift @@ -11,8 +11,8 @@ import SwiftUI @main -struct NAMS: App { - @UIApplicationDelegateAdaptor(NAMSDelegate.self) +struct NAMSApp: App { + @UIApplicationDelegateAdaptor(NAMSAppDelegate.self) var appDelegate @AppStorage(StorageKeys.onboardingFlowComplete) var completedOnboardingFlow = false diff --git a/NAMS/NAMSAppDelegate.swift b/NAMS/NAMSAppDelegate.swift index db4752d..4c62b78 100644 --- a/NAMS/NAMSAppDelegate.swift +++ b/NAMS/NAMSAppDelegate.swift @@ -24,7 +24,7 @@ import SpeziScheduler import SwiftUI -class NAMSDelegate: SpeziAppDelegate { +class NAMSAppDelegate: SpeziAppDelegate { override var configuration: Configuration { Configuration(standard: FHIR()) { if !FeatureFlags.disableFirebase { diff --git a/NAMS/Onboarding/AccountSetup/AccountSetup.swift b/NAMS/Onboarding/AccountSetup/AccountSetup.swift index c151fed..e502475 100644 --- a/NAMS/Onboarding/AccountSetup/AccountSetup.swift +++ b/NAMS/Onboarding/AccountSetup/AccountSetup.swift @@ -18,7 +18,6 @@ struct AccountSetup: View { @Binding private var onboardingSteps: [OnboardingFlow.Step] @EnvironmentObject var account: Account - var body: some View { OnboardingView( contentView: { @@ -34,11 +33,11 @@ struct AccountSetup: View { } }, actionView: { actionView - } + } // TODO can we put the next button in a toolbar? (logged in state is scrollable! ) .onReceive(account.objectWillChange) { if account.signedIn { - onboardingSteps.append(.healthKitPermissions) + onboardingSteps.append(.finished) // Unfortunately, SwiftUI currently animates changes in the navigation path that do not change // the current top view. Therefore we need to do the following async procedure to remove the // `.login` and `.signUp` steps while disabling the animations before and re-enabling them @@ -72,17 +71,21 @@ struct AccountSetup: View { VStack { Group { if account.signedIn { - Text("ACCOUNT_SIGNED_IN_DESCRIPTION") + Text("ACCOUNT_SIGNED_IN_DESCRIPTION") // TODO this text does not wrap to the next line! } else { Text("ACCOUNT_SETUP_DESCRIPTION") } } .multilineTextAlignment(.center) .padding(.vertical, 16) + if account.signedIn { UserView() .padding() Button("Logout", role: .destructive) { + // workaround as of https://github.com/StanfordSpezi/SpeziTemplateApplication/issues/21 + account.signedIn = false + try? Auth.auth().signOut() } } @@ -95,7 +98,7 @@ struct AccountSetup: View { OnboardingActionsView( "ACCOUNT_NEXT".moduleLocalized, action: { - onboardingSteps.append(.healthKitPermissions) + onboardingSteps.append(.finished) } ) } else { @@ -123,7 +126,8 @@ struct AccountSetup: View { struct AccountSetup_Previews: PreviewProvider { @State private static var path: [OnboardingFlow.Step] = [] - + // TODO preview with signed in account! + static var previews: some View { AccountSetup(onboardingSteps: $path) .environmentObject(Account(accountServices: [])) diff --git a/NAMS/Onboarding/AccountSetup/NAMSLogin.swift b/NAMS/Onboarding/AccountSetup/NAMSLogin.swift index 7288e07..689468f 100644 --- a/NAMS/Onboarding/AccountSetup/NAMSLogin.swift +++ b/NAMS/Onboarding/AccountSetup/NAMSLogin.swift @@ -30,8 +30,10 @@ struct NAMSLogin: View { #if DEBUG struct NAMSLogin_Previews: PreviewProvider { static var previews: some View { - NAMSLogin() - .environmentObject(Account(accountServices: [])) + NavigationStack { + NAMSLogin() + .environmentObject(Account(accountServices: [])) + } } } #endif diff --git a/NAMS/Onboarding/AccountSetup/NAMSSignUp.swift b/NAMS/Onboarding/AccountSetup/NAMSSignUp.swift index 7b33309..7c604ec 100644 --- a/NAMS/Onboarding/AccountSetup/NAMSSignUp.swift +++ b/NAMS/Onboarding/AccountSetup/NAMSSignUp.swift @@ -29,8 +29,10 @@ struct NAMSSignUp: View { #if DEBUG struct NAMSSignUp_Previews: PreviewProvider { static var previews: some View { - NAMSSignUp() - .environmentObject(Account(accountServices: [])) + NavigationStack { + NAMSSignUp() + .environmentObject(Account(accountServices: [EmailPasswordAccountService()])) + } } } #endif diff --git a/NAMS/Onboarding/Consent.swift b/NAMS/Onboarding/Consent.swift index e54dc5d..ac1477d 100644 --- a/NAMS/Onboarding/Consent.swift +++ b/NAMS/Onboarding/Consent.swift @@ -37,7 +37,7 @@ struct Consent: View { if !FeatureFlags.disableFirebase { onboardingSteps.append(.accountSetup) } else { - onboardingSteps.append(.healthKitPermissions) + // TODO onboardingSteps.append(.healthKitPermissions) // TODO remove! } } ) diff --git a/NAMS/Onboarding/FinishedSetup.swift b/NAMS/Onboarding/FinishedSetup.swift new file mode 100644 index 0000000..4e9dfbe --- /dev/null +++ b/NAMS/Onboarding/FinishedSetup.swift @@ -0,0 +1,51 @@ +// +// Created by Andreas Bauer on 11.06.23. +// + +import Foundation +import SwiftUI +import SpeziOnboarding + +struct FinishedSetup: View { + @AppStorage(StorageKeys.onboardingFlowComplete) + var completedOnboardingFlow = false + + var body: some View { + OnboardingView( + titleView: { + OnboardingTitleView( + title: "FINISHED_SETUP_TITLE" + ) + }, + contentView: { + Group { + Spacer() + Image(systemName: "gear.badge.checkmark") + .foregroundColor(.accentColor) + .font(.system(size: 150)) + .padding(.vertical, 20) + + Spacer() + Text("FINISHED_SETUP_TEXT") + .multilineTextAlignment(.center) + Spacer() + Spacer() + Spacer() + } + }, + actionView: { + OnboardingActionsView("Start") { + completedOnboardingFlow = true + } + } + ) + } +} + +#if DEBUG +struct FinishedSetup_Previews: PreviewProvider { + static var previews: some View { + FinishedSetup() + } +} +#endif diff --git a/NAMS/Onboarding/InterestingModules.swift b/NAMS/Onboarding/InterestingModules.swift index 0445ea7..cd80b0f 100644 --- a/NAMS/Onboarding/InterestingModules.swift +++ b/NAMS/Onboarding/InterestingModules.swift @@ -38,12 +38,17 @@ struct InterestingModules: View { ], actionText: "INTERESTING_MODULES_BUTTON".moduleLocalized, action: { + // TODO can we put the next button in a toolbar? + onboardingSteps.append(.accountSetup) + + /* #if targetEnvironment(simulator) && (arch(i386) || arch(x86_64)) print("PKCanvas view-related views are currently skipped on Intel-based iOS simulators due to a metal bug on the simulator.") onboardingSteps.append(.accountSetup) #else onboardingSteps.append(.consent) #endif + */ } ) } diff --git a/NAMS/Onboarding/OnboardingFlow.swift b/NAMS/Onboarding/OnboardingFlow.swift index 88affc2..4789d03 100644 --- a/NAMS/Onboarding/OnboardingFlow.swift +++ b/NAMS/Onboarding/OnboardingFlow.swift @@ -12,12 +12,10 @@ import SwiftUI /// Displays an multi-step onboarding flow for the Neurodevelopment Assessment and Monitoring System (NAMS). struct OnboardingFlow: View { enum Step: String, Codable { - case interestingModules - case consent case accountSetup case login case signUp - case healthKitPermissions + case finished } @SceneStorage(StorageKeys.onboardingFlowStep) @@ -25,24 +23,19 @@ struct OnboardingFlow: View { @AppStorage(StorageKeys.onboardingFlowComplete) var completedOnboardingFlow = false - var body: some View { NavigationStack(path: $onboardingSteps) { Welcome(onboardingSteps: $onboardingSteps) .navigationDestination(for: Step.self) { onboardingStep in switch onboardingStep { - case .interestingModules: - InterestingModules(onboardingSteps: $onboardingSteps) - case .consent: - Consent(onboardingSteps: $onboardingSteps) case .accountSetup: AccountSetup(onboardingSteps: $onboardingSteps) case .login: NAMSLogin() case .signUp: NAMSSignUp() - case .healthKitPermissions: - HealthKitPermissions() + case .finished: + FinishedSetup() } } .navigationBarTitleDisplayMode(.inline) diff --git a/NAMS/Onboarding/Welcome.swift b/NAMS/Onboarding/Welcome.swift index 8b32352..76da48d 100644 --- a/NAMS/Onboarding/Welcome.swift +++ b/NAMS/Onboarding/Welcome.swift @@ -17,27 +17,27 @@ struct Welcome: View { var body: some View { OnboardingView( title: "WELCOME_TITLE".moduleLocalized, - subtitle: "WELCOME_SUBTITLE".moduleLocalized, + subtitle: nil, areas: [ .init( - icon: Image(systemName: "apps.iphone"), + icon: Image(systemName: "person.2.fill"), title: "WELCOME_AREA1_TITLE".moduleLocalized, description: "WELCOME_AREA1_DESCRIPTION".moduleLocalized ), .init( - icon: Image(systemName: "shippingbox.fill"), + icon: Image(systemName: "list.clipboard.fill"), title: "WELCOME_AREA2_TITLE".moduleLocalized, description: "WELCOME_AREA2_DESCRIPTION".moduleLocalized ), .init( - icon: Image(systemName: "list.bullet.clipboard.fill"), + icon: Image(systemName: "doc.text.below.ecg.fill"), title: "WELCOME_AREA3_TITLE".moduleLocalized, description: "WELCOME_AREA3_DESCRIPTION".moduleLocalized ) ], actionText: "WELCOME_BUTTON".moduleLocalized, action: { - onboardingSteps.append(.interestingModules) + onboardingSteps.append(.accountSetup) } ) } diff --git a/NAMS/Resources/Localizable.strings b/NAMS/Resources/Localizable.strings index d965a96..eefdd18 100644 --- a/NAMS/Resources/Localizable.strings +++ b/NAMS/Resources/Localizable.strings @@ -17,19 +17,19 @@ // MARK: - Onboarding // MARK: Welcome -"WELCOME_TITLE" = "Spezi\nNeurodevelopment Assessment and Monitoring System (NAMS)"; +"WELCOME_TITLE" = "Neurodevelopment Assessment and Monitoring System (NAMS)"; "WELCOME_SUBTITLE" = "This application demonstrates several Spezi features & modules."; -"WELCOME_AREA1_TITLE" = "The Spezi Framework"; -"WELCOME_AREA1_DESCRIPTION" = "The Spezi Framework builds the foundation of the NAMS application."; +"WELCOME_AREA1_TITLE" = "Patient Management"; +"WELCOME_AREA1_DESCRIPTION" = "The NAMS App helps you to manage multiple patients at once."; -"WELCOME_AREA2_TITLE" = "Swift Package Manager"; -"WELCOME_AREA2_DESCRIPTION" = "Spezi uses the Swift Package Manager to import it as a dependency."; +"WELCOME_AREA2_TITLE" = "Questionnaires"; +"WELCOME_AREA2_DESCRIPTION" = "NAMS provides you with several questionnaires to assess conditions of your patients."; -"WELCOME_AREA3_TITLE" = "Spezi Modules"; -"WELCOME_AREA3_DESCRIPTION" = "Spezi offers several modules including HealthKit integration, questionnaires, and more ..."; +"WELCOME_AREA3_TITLE" = "EEG Recordings"; +"WELCOME_AREA3_DESCRIPTION" = "NAMS offers integration with consumer-grade EEG headbands for easy and scalable EEG measurements."; -"WELCOME_BUTTON" = "Learn More"; +"WELCOME_BUTTON" = "Continue"; // MARK: Interesting Modules "INTERESTING_MODULES_TITLE" = "Interesting Modules"; @@ -47,7 +47,7 @@ "INTERESTING_MODULES_AREA4_TITLE" = "HealthKit Data Source"; "INTERESTING_MODULES_AREA4_DESCRIPTION" = "The HealthKit data source module allows you to fetch data from HealthKit and e.g. transform it to FHIR resources."; -"INTERESTING_MODULES_BUTTON" = "Next"; +"INTERESTING_MODULES_BUTTON" = "Continue"; // MARK: Consent @@ -59,8 +59,8 @@ // MARK: Account "ACCOUNT_TITLE" = "Your Account"; -"ACCOUNT_SUBTITLE" = "The Neurodevelopment Assessment and Monitoring System (NAMS) demonstrates the usage of the Firebase Account Module."; -"ACCOUNT_SETUP_DESCRIPTION" = "The login and sign up buttons use the Account Login and SignUp views."; +"ACCOUNT_SUBTITLE" = "The Neurodevelopment Assessment and Monitoring System (NAMS) uses your account to connect and manage patient data."; +"ACCOUNT_SETUP_DESCRIPTION" = "Please sign up to create a new account or log into an existing one."; "ACCOUNT_SIGNED_IN_DESCRIPTION" = "You are successfully signed in with the following account:"; "ACCOUNT_NEXT" = "Next"; "ACCOUNT_SIGN_UP" = "Sign Up"; @@ -81,6 +81,9 @@ "HEALTHKIT_PERMISSIONS_DESCRIPTION" = "This onboarding step allows you to customize the onboarding flow to explain how the application uses the HealhtKit data and allows a user to cusomize the selection."; "HEALTHKIT_PERMISSIONS_BUTTON" = "Grant Access"; +// MARK: Finished Setup +FINISHED_SETUP_TITLE = "Ready To Go"; +FINISHED_SETUP_TEXT = "You completed all the onboarding steps!\n You can now use the app to manage patients, conduct questionnaires and do EEG recordings."; // MARK: - Mock Upload Data Storage Provider "MOCK_UPLOAD_TAB_TITLE" = "Mock Upload"; diff --git a/NAMS/Schedule/NAMSTaskContext.swift b/NAMS/Schedule/NAMSTaskContext.swift index 6dbb981..f938b6b 100644 --- a/NAMS/Schedule/NAMSTaskContext.swift +++ b/NAMS/Schedule/NAMSTaskContext.swift @@ -13,7 +13,7 @@ import SpeziFHIR /// /// We currently only support `Questionnaire`s, more cases can be added in the future. enum NAMSTaskContext: Codable, Identifiable { - /// The task schould display a `Questionnaire`. + /// The task should display a `Questionnaire`. case questionnaire(Questionnaire) diff --git a/NAMS/SharedContext/FeatureFlags.swift b/NAMS/SharedContext/FeatureFlags.swift index 9a152ca..f5d5a0a 100644 --- a/NAMS/SharedContext/FeatureFlags.swift +++ b/NAMS/SharedContext/FeatureFlags.swift @@ -6,7 +6,7 @@ // SPDX-License-Identifier: MIT // -/// A collection of feature flags for the PAWS app. +/// A collection of feature flags for the NAMS app. enum FeatureFlags { /// Skips the onboarding flow to enable easier development of features in the application and to allow UI tests to skip the onboarding flow. static let skipOnboarding = CommandLine.arguments.contains("--skipOnboarding") From 80695db505cadeb601f5f1e2b3d029d4eb59049b Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Mon, 12 Jun 2023 01:33:04 +0200 Subject: [PATCH 04/13] Adjust minor styling --- NAMS/Onboarding/AccountSetup/AccountSetup.swift | 2 ++ NAMS/Onboarding/AccountSetup/UserView.swift | 6 ++++-- NAMS/Onboarding/FinishedSetup.swift | 6 ++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/NAMS/Onboarding/AccountSetup/AccountSetup.swift b/NAMS/Onboarding/AccountSetup/AccountSetup.swift index e502475..5e7135d 100644 --- a/NAMS/Onboarding/AccountSetup/AccountSetup.swift +++ b/NAMS/Onboarding/AccountSetup/AccountSetup.swift @@ -58,8 +58,10 @@ struct AccountSetup: View { Group { if account.signedIn { Image(systemName: "person.badge.shield.checkmark.fill") + .symbolRenderingMode(.hierarchical) } else { Image(systemName: "person.fill.badge.plus") + .symbolRenderingMode(.hierarchical) } } .font(.system(size: 150)) diff --git a/NAMS/Onboarding/AccountSetup/UserView.swift b/NAMS/Onboarding/AccountSetup/UserView.swift index 1461a36..731f146 100644 --- a/NAMS/Onboarding/AccountSetup/UserView.swift +++ b/NAMS/Onboarding/AccountSetup/UserView.swift @@ -47,7 +47,7 @@ struct UserView: View { Spacer() } else { Spacer() - VStack(spacing: 16) { + HStack(spacing: 16) { ProgressView() Text("USER_VIEW_LOADING") .multilineTextAlignment(.center) @@ -62,9 +62,11 @@ struct UserView: View { #if DEBUG struct SwiftUIView_Previews: PreviewProvider { static var previews: some View { - UserView() + var userView = UserView() + userView .padding() .environmentObject(FirebaseAccountConfiguration(emulatorSettings: (host: "localhost", port: 9099))) + .environmentObject(Account(accountServices: [])) } } #endif diff --git a/NAMS/Onboarding/FinishedSetup.swift b/NAMS/Onboarding/FinishedSetup.swift index 4e9dfbe..0c8927c 100644 --- a/NAMS/Onboarding/FinishedSetup.swift +++ b/NAMS/Onboarding/FinishedSetup.swift @@ -3,8 +3,8 @@ // import Foundation -import SwiftUI import SpeziOnboarding +import SwiftUI struct FinishedSetup: View { @AppStorage(StorageKeys.onboardingFlowComplete) @@ -21,10 +21,12 @@ struct FinishedSetup: View { Group { Spacer() Image(systemName: "gear.badge.checkmark") - .foregroundColor(.accentColor) + .symbolRenderingMode(.palette) + .foregroundStyle(Color(uiColor: .systemGreen), Color.accentColor) .font(.system(size: 150)) .padding(.vertical, 20) + Spacer() Text("FINISHED_SETUP_TEXT") .multilineTextAlignment(.center) From ebcc0962b184c1cf3f539ce30b5928df324c9b66 Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Mon, 12 Jun 2023 01:59:08 +0200 Subject: [PATCH 05/13] Fix some typos in the locales --- NAMS/Resources/Localizable.strings | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NAMS/Resources/Localizable.strings b/NAMS/Resources/Localizable.strings index eefdd18..af08ff1 100644 --- a/NAMS/Resources/Localizable.strings +++ b/NAMS/Resources/Localizable.strings @@ -78,12 +78,12 @@ // MARK: HealthKit "HEALTHKIT_PERMISSIONS_TITLE" = "HealthKit Access"; "HEALTHKIT_PERMISSIONS_SUBTITLE" = "Spezi can access data from HealthKit using the HealthKitDataSource module."; -"HEALTHKIT_PERMISSIONS_DESCRIPTION" = "This onboarding step allows you to customize the onboarding flow to explain how the application uses the HealhtKit data and allows a user to cusomize the selection."; +"HEALTHKIT_PERMISSIONS_DESCRIPTION" = "This onboarding step allows you to customize the onboarding flow to explain how the application uses the HealthKit data and allows a user to customize the selection."; "HEALTHKIT_PERMISSIONS_BUTTON" = "Grant Access"; // MARK: Finished Setup FINISHED_SETUP_TITLE = "Ready To Go"; -FINISHED_SETUP_TEXT = "You completed all the onboarding steps!\n You can now use the app to manage patients, conduct questionnaires and do EEG recordings."; +FINISHED_SETUP_TEXT = "You completed all the onboarding steps!\n You can now use the app to manage patients, conduct questionnaires and EEG recordings."; // MARK: - Mock Upload Data Storage Provider "MOCK_UPLOAD_TAB_TITLE" = "Mock Upload"; From 973d3bc9a0adc39e59b01bab08b620676e6ef1ac Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Mon, 12 Jun 2023 02:09:54 +0200 Subject: [PATCH 06/13] Contributor list --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 8800fac..a00bb76 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -11,4 +11,5 @@ SPDX-License-Identifier: MIT Neurodevelopment Assessment and Monitoring System (NAMS) Contributors ================================= +* [Andreas Bauer](https://github.com/Supereg) * [Paul Schmiedmayer](https://github.com/PSchmiedmayer) From c044461d1bc358c628cd05a71756e90aa7d66d98 Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Mon, 12 Jun 2023 13:57:58 +0200 Subject: [PATCH 07/13] Fix REUSE compliance --- NAMS/Onboarding/FinishedSetup.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NAMS/Onboarding/FinishedSetup.swift b/NAMS/Onboarding/FinishedSetup.swift index 0c8927c..3cf9734 100644 --- a/NAMS/Onboarding/FinishedSetup.swift +++ b/NAMS/Onboarding/FinishedSetup.swift @@ -1,5 +1,9 @@ // -// Created by Andreas Bauer on 11.06.23. +// This source file is part of the Neurodevelopment Assessment and Monitoring System (NAMS) project +// +// SPDX-FileCopyrightText: 2023 Stanford University +// +// SPDX-License-Identifier: MIT // import Foundation From 76acbc19cb85fb72f76afd57e426be86ff358970 Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Mon, 12 Jun 2023 14:28:24 +0200 Subject: [PATCH 08/13] Resolved swiftlint issues --- NAMS/Helper/CodableArray+RawRepresentable.swift | 2 -- NAMS/Onboarding/AccountSetup/AccountSetup.swift | 6 ++---- NAMS/Onboarding/Consent.swift | 2 +- NAMS/Onboarding/InterestingModules.swift | 1 - 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/NAMS/Helper/CodableArray+RawRepresentable.swift b/NAMS/Helper/CodableArray+RawRepresentable.swift index 9973603..a659c1f 100644 --- a/NAMS/Helper/CodableArray+RawRepresentable.swift +++ b/NAMS/Helper/CodableArray+RawRepresentable.swift @@ -8,8 +8,6 @@ import Foundation - -// TODO why is this used forcing JSON? extension Array: RawRepresentable where Element: Codable { public var rawValue: String { guard let data = try? JSONEncoder().encode(self), diff --git a/NAMS/Onboarding/AccountSetup/AccountSetup.swift b/NAMS/Onboarding/AccountSetup/AccountSetup.swift index 5e7135d..9b994e5 100644 --- a/NAMS/Onboarding/AccountSetup/AccountSetup.swift +++ b/NAMS/Onboarding/AccountSetup/AccountSetup.swift @@ -33,7 +33,7 @@ struct AccountSetup: View { } }, actionView: { actionView - } // TODO can we put the next button in a toolbar? (logged in state is scrollable! + } ) .onReceive(account.objectWillChange) { if account.signedIn { @@ -73,7 +73,7 @@ struct AccountSetup: View { VStack { Group { if account.signedIn { - Text("ACCOUNT_SIGNED_IN_DESCRIPTION") // TODO this text does not wrap to the next line! + Text("ACCOUNT_SIGNED_IN_DESCRIPTION") } else { Text("ACCOUNT_SETUP_DESCRIPTION") } @@ -127,8 +127,6 @@ struct AccountSetup: View { #if DEBUG struct AccountSetup_Previews: PreviewProvider { @State private static var path: [OnboardingFlow.Step] = [] - - // TODO preview with signed in account! static var previews: some View { AccountSetup(onboardingSteps: $path) diff --git a/NAMS/Onboarding/Consent.swift b/NAMS/Onboarding/Consent.swift index ac1477d..94108bf 100644 --- a/NAMS/Onboarding/Consent.swift +++ b/NAMS/Onboarding/Consent.swift @@ -37,7 +37,7 @@ struct Consent: View { if !FeatureFlags.disableFirebase { onboardingSteps.append(.accountSetup) } else { - // TODO onboardingSteps.append(.healthKitPermissions) // TODO remove! + onboardingSteps.append(.finished) } } ) diff --git a/NAMS/Onboarding/InterestingModules.swift b/NAMS/Onboarding/InterestingModules.swift index cd80b0f..31c34ed 100644 --- a/NAMS/Onboarding/InterestingModules.swift +++ b/NAMS/Onboarding/InterestingModules.swift @@ -38,7 +38,6 @@ struct InterestingModules: View { ], actionText: "INTERESTING_MODULES_BUTTON".moduleLocalized, action: { - // TODO can we put the next button in a toolbar? onboardingSteps.append(.accountSetup) /* From 15d5707ae8e43fca07117153258c7d13f3c0466d Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Mon, 12 Jun 2023 14:58:54 +0200 Subject: [PATCH 09/13] Fix tests --- NAMS/Resources/Localizable.strings | 2 +- NAMSUITests/HealthKitUploadTests.swift | 3 + NAMSUITests/OnboardingTests.swift | 79 ++++++++++++++++---------- 3 files changed, 53 insertions(+), 31 deletions(-) diff --git a/NAMS/Resources/Localizable.strings b/NAMS/Resources/Localizable.strings index af08ff1..a33bf27 100644 --- a/NAMS/Resources/Localizable.strings +++ b/NAMS/Resources/Localizable.strings @@ -62,7 +62,7 @@ "ACCOUNT_SUBTITLE" = "The Neurodevelopment Assessment and Monitoring System (NAMS) uses your account to connect and manage patient data."; "ACCOUNT_SETUP_DESCRIPTION" = "Please sign up to create a new account or log into an existing one."; "ACCOUNT_SIGNED_IN_DESCRIPTION" = "You are successfully signed in with the following account:"; -"ACCOUNT_NEXT" = "Next"; +"ACCOUNT_NEXT" = "Continue"; "ACCOUNT_SIGN_UP" = "Sign Up"; "ACCOUNT_LOGIN" = "Login"; diff --git a/NAMSUITests/HealthKitUploadTests.swift b/NAMSUITests/HealthKitUploadTests.swift index bf781f9..bc2ea59 100644 --- a/NAMSUITests/HealthKitUploadTests.swift +++ b/NAMSUITests/HealthKitUploadTests.swift @@ -13,6 +13,7 @@ import XCTHealthKit class HealthKitUploadTests: XCTestCase { override func setUpWithError() throws { + throw XCTSkip("HelathKit Tests are currently skipped!") try super.setUpWithError() try disablePasswordAutofill() @@ -26,6 +27,8 @@ class HealthKitUploadTests: XCTestCase { func testHealthKitMockUpload() throws { + throw XCTSkip("HelathKit Tests are currently skipped!") + let app = XCUIApplication() try app.conductOnboardingIfNeeded() diff --git a/NAMSUITests/OnboardingTests.swift b/NAMSUITests/OnboardingTests.swift index 09038b1..683e302 100644 --- a/NAMSUITests/OnboardingTests.swift +++ b/NAMSUITests/OnboardingTests.swift @@ -47,31 +47,33 @@ extension XCUIApplication { func navigateOnboardingFlow(assertThatHealthKitConsentIsShown: Bool = true) throws { try navigateOnboardingFlowWelcome() - try navigateOnboardingFlowInterestingModules() - if staticTexts["Consent Example"].waitForExistence(timeout: 5) { - try navigateOnboardingFlowConsent() - } + // try navigateOnboardingFlowInterestingModules() + // if staticTexts["Consent Example"].waitForExistence(timeout: 5) { + // try navigateOnboardingFlowConsent() + // } try navigateOnboardingAccount() - try navigateOnboardingFlowHealthKitAccess(assertThatHealthKitConsentIsShown: assertThatHealthKitConsentIsShown) + // try navigateOnboardingFlowHealthKitAccess(assertThatHealthKitConsentIsShown: assertThatHealthKitConsentIsShown) + try navigateFinishedSetup() } private func navigateOnboardingFlowWelcome() throws { - XCTAssertTrue(staticTexts["Spezi\nNeurodevelopment Assessment and Monitoring System (NAMS)"].waitForExistence(timeout: 2)) - - XCTAssertTrue(buttons["Learn More"].waitForExistence(timeout: 2)) - buttons["Learn More"].tap() + XCTAssertTrue(staticTexts["Neurodevelopment Assessment and Monitoring System (NAMS)"].waitForExistence(timeout: 2)) + + let continueButton = buttons["Continue"] + XCTAssertTrue(continueButton.waitForExistence(timeout: 2)) + continueButton.tap() } private func navigateOnboardingFlowInterestingModules() throws { XCTAssertTrue(staticTexts["Interesting Modules"].waitForExistence(timeout: 2)) for _ in 1..<4 { - XCTAssertTrue(buttons["Next"].waitForExistence(timeout: 2)) - buttons["Next"].tap() + XCTAssertTrue(buttons["Continue"].waitForExistence(timeout: 2)) + buttons["Continue"].tap() } - XCTAssertTrue(buttons["Next"].waitForExistence(timeout: 2)) - buttons["Next"].tap() + XCTAssertTrue(buttons["Continue"].waitForExistence(timeout: 2)) + buttons["Continue"].tap() } private func navigateOnboardingFlowConsent() throws { @@ -94,50 +96,67 @@ extension XCUIApplication { private func navigateOnboardingAccount() throws { XCTAssertTrue(staticTexts["Your Account"].waitForExistence(timeout: 2)) - - guard !buttons["Next"].waitForExistence(timeout: 5) else { - buttons["Next"].tap() - return + + if buttons["Continue"].waitForExistence(timeout: 5) { + let logoutButton = buttons["Logout"] + XCTAssertTrue(logoutButton.waitForExistence(timeout: 2)) + logoutButton.tap() + + XCTAssertTrue(staticTexts["Your Account"].waitForExistence(timeout: 2)) } + try testOnboardingWithoutAccount() + } + + private func testOnboardingWithoutAccount() throws { + XCTAssertTrue(staticTexts["Your Account"].waitForExistence(timeout: 2)) + XCTAssertTrue(buttons["Sign Up"].waitForExistence(timeout: 2)) buttons["Sign Up"].tap() - + XCTAssertTrue(navigationBars.staticTexts["Sign Up"].waitForExistence(timeout: 2)) XCTAssertTrue(images["App Icon"].waitForExistence(timeout: 2)) XCTAssertTrue(buttons["Email and Password"].waitForExistence(timeout: 2)) - + buttons["Email and Password"].tap() - + try textFields["Enter your email ..."].enter(value: "leland@stanford.edu") swipeUp() - + secureTextFields["Enter your password ..."].tap() secureTextFields["Enter your password ..."].typeText("StanfordRocks") swipeUp() secureTextFields["Repeat your password ..."].tap() secureTextFields["Repeat your password ..."].typeText("StanfordRocks") swipeUp() - + try textFields["Enter your first name ..."].enter(value: "Leland") staticTexts["Repeat\nPassword"].swipeUp() - + try textFields["Enter your last name ..."].enter(value: "Stanford") staticTexts["Repeat\nPassword"].swipeUp() - + collectionViews.buttons["Sign Up"].tap() - + sleep(3) - - if staticTexts["HealthKit Access"].waitForExistence(timeout: 5) && navigationBars.buttons["Back"].waitForExistence(timeout: 5) { + + if staticTexts["Ready To Go"].waitForExistence(timeout: 5) && navigationBars.buttons["Back"].waitForExistence(timeout: 5) { navigationBars.buttons["Back"].tap() - + XCTAssertTrue(staticTexts["Leland Stanford"].waitForExistence(timeout: 2)) XCTAssertTrue(staticTexts["leland@stanford.edu"].waitForExistence(timeout: 2)) - XCTAssertTrue(scrollViews.otherElements.buttons["Next"].waitForExistence(timeout: 2)) - scrollViews.otherElements.buttons["Next"].tap() + XCTAssertTrue(scrollViews.otherElements.buttons["Continue"].waitForExistence(timeout: 2)) + scrollViews.otherElements.buttons["Continue"].tap() } } + + private func navigateFinishedSetup() throws { + XCTAssertTrue(staticTexts["Ready To Go"].waitForExistence(timeout: 2)) + + let startButton = buttons["Start"] + XCTAssertTrue(startButton.waitForExistence(timeout: 2)) + startButton.tap() + } private func navigateOnboardingFlowHealthKitAccess(assertThatHealthKitConsentIsShown: Bool = true) throws { XCTAssertTrue(staticTexts["HealthKit Access"].waitForExistence(timeout: 2)) From 096e4ed91c70cad6cd1c4dcf1dd7f87bc51faa3d Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Mon, 12 Jun 2023 15:39:00 +0200 Subject: [PATCH 10/13] Fix weirdness about siwftlint attributes warning --- NAMS/Onboarding/AccountSetup/AccountSetup.swift | 6 +++--- NAMS/Onboarding/AccountSetup/UserView.swift | 2 +- NAMS/Schedule/ScheduleView.swift | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/NAMS/Onboarding/AccountSetup/AccountSetup.swift b/NAMS/Onboarding/AccountSetup/AccountSetup.swift index 9b994e5..854c11e 100644 --- a/NAMS/Onboarding/AccountSetup/AccountSetup.swift +++ b/NAMS/Onboarding/AccountSetup/AccountSetup.swift @@ -54,7 +54,7 @@ struct AccountSetup: View { } @ViewBuilder - private var accountImage: some View { // swiftlint:disable:this attributes + private var accountImage: some View { Group { if account.signedIn { Image(systemName: "person.badge.shield.checkmark.fill") @@ -69,7 +69,7 @@ struct AccountSetup: View { } @ViewBuilder - private var accountDescription: some View { // swiftlint:disable:this attributes + private var accountDescription: some View { VStack { Group { if account.signedIn { @@ -95,7 +95,7 @@ struct AccountSetup: View { } @ViewBuilder - private var actionView: some View { // swiftlint:disable:this attributes + private var actionView: some View { if account.signedIn { OnboardingActionsView( "ACCOUNT_NEXT".moduleLocalized, diff --git a/NAMS/Onboarding/AccountSetup/UserView.swift b/NAMS/Onboarding/AccountSetup/UserView.swift index 731f146..7af1680 100644 --- a/NAMS/Onboarding/AccountSetup/UserView.swift +++ b/NAMS/Onboarding/AccountSetup/UserView.swift @@ -30,7 +30,7 @@ struct UserView: View { } @ViewBuilder - private var userInformation: some View { // swiftlint:disable:this attributes + private var userInformation: some View { HStack(spacing: 16) { if account.signedIn, let user = firebaseAccountConfiguration.user, diff --git a/NAMS/Schedule/ScheduleView.swift b/NAMS/Schedule/ScheduleView.swift index 6327391..2cc6fe6 100644 --- a/NAMS/Schedule/ScheduleView.swift +++ b/NAMS/Schedule/ScheduleView.swift @@ -53,7 +53,7 @@ struct ScheduleView: View { private func destination(withContext eventContext: EventContext) -> some View { @ViewBuilder - var destination: some View { // swiftlint:disable:this attributes + var destination: some View { switch eventContext.task.context { case let .questionnaire(questionnaire): QuestionnaireView(questionnaire: questionnaire) { _ in From cdeadad47ac6ed0be7db2aa0380b844ce580e5bc Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Mon, 12 Jun 2023 17:46:05 +0200 Subject: [PATCH 11/13] Remove unused components --- NAMS.xcodeproj/project.pbxproj | 63 ---------------- .../xcshareddata/swiftpm/Package.resolved | 36 ---------- NAMS/NAMSAppDelegate.swift | 18 ----- NAMS/Onboarding/AccountSetup/UserView.swift | 3 +- NAMS/Onboarding/Consent.swift | 62 ---------------- NAMS/Onboarding/HealthKitPermissions.swift | 71 ------------------- NAMS/Onboarding/InterestingModules.swift | 71 ------------------- 7 files changed, 1 insertion(+), 323 deletions(-) delete mode 100644 NAMS/Onboarding/Consent.swift delete mode 100644 NAMS/Onboarding/HealthKitPermissions.swift delete mode 100644 NAMS/Onboarding/InterestingModules.swift diff --git a/NAMS.xcodeproj/project.pbxproj b/NAMS.xcodeproj/project.pbxproj index 7e61cf1..be7d5b2 100644 --- a/NAMS.xcodeproj/project.pbxproj +++ b/NAMS.xcodeproj/project.pbxproj @@ -22,10 +22,7 @@ 2FC9759F2978E39600BA99FE /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 2FC9759E2978E39600BA99FE /* Localizable.strings */; }; 2FC975A82978F11A00BA99FE /* Home.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FC975A72978F11A00BA99FE /* Home.swift */; }; 2FE5DC2629EDD38A004B9AB4 /* Contacts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC2529EDD38A004B9AB4 /* Contacts.swift */; }; - 2FE5DC3529EDD7CA004B9AB4 /* Consent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC2F29EDD7CA004B9AB4 /* Consent.swift */; }; - 2FE5DC3629EDD7CA004B9AB4 /* HealthKitPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC3029EDD7CA004B9AB4 /* HealthKitPermissions.swift */; }; 2FE5DC3729EDD7CA004B9AB4 /* OnboardingFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC3129EDD7CA004B9AB4 /* OnboardingFlow.swift */; }; - 2FE5DC3829EDD7CA004B9AB4 /* InterestingModules.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC3229EDD7CA004B9AB4 /* InterestingModules.swift */; }; 2FE5DC3929EDD7CA004B9AB4 /* String+ModuleLocalized.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC3329EDD7CA004B9AB4 /* String+ModuleLocalized.swift */; }; 2FE5DC3A29EDD7CA004B9AB4 /* Welcome.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC3429EDD7CA004B9AB4 /* Welcome.swift */; }; 2FE5DC4029EDD7EE004B9AB4 /* FeatureFlags.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DC3E29EDD7ED004B9AB4 /* FeatureFlags.swift */; }; @@ -44,12 +41,10 @@ 2FE5DC6A29EDD8A9004B9AB4 /* SpeziFHIR in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC6929EDD8A9004B9AB4 /* SpeziFHIR */; }; 2FE5DC6C29EDD8A9004B9AB4 /* SpeziFHIRMockDataStorageProvider in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC6B29EDD8A9004B9AB4 /* SpeziFHIRMockDataStorageProvider */; }; 2FE5DC6F29EDD8BF004B9AB4 /* SpeziFHIRToFirestoreAdapter in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC6E29EDD8BF004B9AB4 /* SpeziFHIRToFirestoreAdapter */; }; - 2FE5DC7229EDD8D3004B9AB4 /* SpeziHealthKit in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC7129EDD8D3004B9AB4 /* SpeziHealthKit */; }; 2FE5DC7529EDD8E6004B9AB4 /* SpeziFirebaseAccount in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC7429EDD8E6004B9AB4 /* SpeziFirebaseAccount */; }; 2FE5DC7729EDD8E6004B9AB4 /* SpeziFirebaseConfiguration in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC7629EDD8E6004B9AB4 /* SpeziFirebaseConfiguration */; }; 2FE5DC7929EDD8E6004B9AB4 /* SpeziFirestore in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC7829EDD8E6004B9AB4 /* SpeziFirestore */; }; 2FE5DC7B29EDD8E6004B9AB4 /* SpeziFirestorePrefixUserIdAdapter in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC7A29EDD8E6004B9AB4 /* SpeziFirestorePrefixUserIdAdapter */; }; - 2FE5DC7E29EDD907004B9AB4 /* SpeziHealthKitToFHIRAdapter in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC7D29EDD907004B9AB4 /* SpeziHealthKitToFHIRAdapter */; }; 2FE5DC8129EDD91D004B9AB4 /* SpeziOnboarding in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC8029EDD91D004B9AB4 /* SpeziOnboarding */; }; 2FE5DC8429EDD934004B9AB4 /* SpeziQuestionnaire in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC8329EDD934004B9AB4 /* SpeziQuestionnaire */; }; 2FE5DC8729EDD950004B9AB4 /* SpeziScheduler in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC8629EDD950004B9AB4 /* SpeziScheduler */; }; @@ -57,7 +52,6 @@ 2FE5DC8C29EDD972004B9AB4 /* SpeziSecureStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC8B29EDD972004B9AB4 /* SpeziSecureStorage */; }; 2FE5DC8F29EDD980004B9AB4 /* SpeziViews in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC8E29EDD980004B9AB4 /* SpeziViews */; }; 2FE5DC9929EDD9D9004B9AB4 /* XCTestExtensions in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC9829EDD9D9004B9AB4 /* XCTestExtensions */; }; - 2FE5DC9C29EDD9EF004B9AB4 /* XCTHealthKit in Frameworks */ = {isa = PBXBuildFile; productRef = 2FE5DC9B29EDD9EF004B9AB4 /* XCTHealthKit */; }; 2FE5DCAE29EE6107004B9AB4 /* IconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DCA929EE6107004B9AB4 /* IconView.swift */; }; 2FE5DCAF29EE6107004B9AB4 /* NAMSSignUp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DCAA29EE6107004B9AB4 /* NAMSSignUp.swift */; }; 2FE5DCB029EE6107004B9AB4 /* UserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DCAB29EE6107004B9AB4 /* UserView.swift */; }; @@ -102,10 +96,7 @@ 2FE5DC2529EDD38A004B9AB4 /* Contacts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contacts.swift; sourceTree = ""; }; 2FE5DC2A29EDD78D004B9AB4 /* AppIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = AppIcon.png; sourceTree = ""; }; 2FE5DC2C29EDD78E004B9AB4 /* ConsentDocument.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = ConsentDocument.md; sourceTree = ""; }; - 2FE5DC2F29EDD7CA004B9AB4 /* Consent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Consent.swift; sourceTree = ""; }; - 2FE5DC3029EDD7CA004B9AB4 /* HealthKitPermissions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HealthKitPermissions.swift; sourceTree = ""; }; 2FE5DC3129EDD7CA004B9AB4 /* OnboardingFlow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingFlow.swift; sourceTree = ""; }; - 2FE5DC3229EDD7CA004B9AB4 /* InterestingModules.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InterestingModules.swift; sourceTree = ""; }; 2FE5DC3329EDD7CA004B9AB4 /* String+ModuleLocalized.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+ModuleLocalized.swift"; sourceTree = ""; }; 2FE5DC3429EDD7CA004B9AB4 /* Welcome.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Welcome.swift; sourceTree = ""; }; 2FE5DC3E29EDD7ED004B9AB4 /* FeatureFlags.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureFlags.swift; sourceTree = ""; }; @@ -147,9 +138,7 @@ 2FE5DC8C29EDD972004B9AB4 /* SpeziSecureStorage in Frameworks */, 2FE5DC6F29EDD8BF004B9AB4 /* SpeziFHIRToFirestoreAdapter in Frameworks */, 2FE5DC7529EDD8E6004B9AB4 /* SpeziFirebaseAccount in Frameworks */, - 2FE5DC7229EDD8D3004B9AB4 /* SpeziHealthKit in Frameworks */, 2FE5DC7B29EDD8E6004B9AB4 /* SpeziFirestorePrefixUserIdAdapter in Frameworks */, - 2FE5DC7E29EDD907004B9AB4 /* SpeziHealthKitToFHIRAdapter in Frameworks */, 2F49B7762980407C00BCB272 /* Spezi in Frameworks */, 2FE5DC8F29EDD980004B9AB4 /* SpeziViews in Frameworks */, 2FE5DC8729EDD950004B9AB4 /* SpeziScheduler in Frameworks */, @@ -173,7 +162,6 @@ buildActionMask = 2147483647; files = ( 2FE5DC9929EDD9D9004B9AB4 /* XCTestExtensions in Frameworks */, - 2FE5DC9C29EDD9EF004B9AB4 /* XCTHealthKit in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -210,9 +198,6 @@ isa = PBXGroup; children = ( 2FE5DCA829EE6107004B9AB4 /* AccountSetup */, - 2FE5DC2F29EDD7CA004B9AB4 /* Consent.swift */, - 2FE5DC3029EDD7CA004B9AB4 /* HealthKitPermissions.swift */, - 2FE5DC3229EDD7CA004B9AB4 /* InterestingModules.swift */, 2FE5DC3129EDD7CA004B9AB4 /* OnboardingFlow.swift */, 2FE5DC3329EDD7CA004B9AB4 /* String+ModuleLocalized.swift */, 2FE5DC3429EDD7CA004B9AB4 /* Welcome.swift */, @@ -368,12 +353,10 @@ 2FE5DC6929EDD8A9004B9AB4 /* SpeziFHIR */, 2FE5DC6B29EDD8A9004B9AB4 /* SpeziFHIRMockDataStorageProvider */, 2FE5DC6E29EDD8BF004B9AB4 /* SpeziFHIRToFirestoreAdapter */, - 2FE5DC7129EDD8D3004B9AB4 /* SpeziHealthKit */, 2FE5DC7429EDD8E6004B9AB4 /* SpeziFirebaseAccount */, 2FE5DC7629EDD8E6004B9AB4 /* SpeziFirebaseConfiguration */, 2FE5DC7829EDD8E6004B9AB4 /* SpeziFirestore */, 2FE5DC7A29EDD8E6004B9AB4 /* SpeziFirestorePrefixUserIdAdapter */, - 2FE5DC7D29EDD907004B9AB4 /* SpeziHealthKitToFHIRAdapter */, 2FE5DC8029EDD91D004B9AB4 /* SpeziOnboarding */, 2FE5DC8329EDD934004B9AB4 /* SpeziQuestionnaire */, 2FE5DC8629EDD950004B9AB4 /* SpeziScheduler */, @@ -419,7 +402,6 @@ name = NAMSUITests; packageProductDependencies = ( 2FE5DC9829EDD9D9004B9AB4 /* XCTestExtensions */, - 2FE5DC9B29EDD9EF004B9AB4 /* XCTHealthKit */, ); productName = NAMSUITests; productReference = 653A256728338800005D4D48 /* NAMSUITests.xctest */; @@ -463,9 +445,7 @@ 2FE5DC6529EDD894004B9AB4 /* XCRemoteSwiftPackageReference "SpeziContact" */, 2FE5DC6829EDD8A9004B9AB4 /* XCRemoteSwiftPackageReference "SpeziFHIR" */, 2FE5DC6D29EDD8BF004B9AB4 /* XCRemoteSwiftPackageReference "SpeziFHIRtoFirestoreAdapter" */, - 2FE5DC7029EDD8D3004B9AB4 /* XCRemoteSwiftPackageReference "SpeziHealthKit" */, 2FE5DC7329EDD8E6004B9AB4 /* XCRemoteSwiftPackageReference "SpeziFirebase" */, - 2FE5DC7C29EDD907004B9AB4 /* XCRemoteSwiftPackageReference "SpeziHealthKitToFHIRAdapter" */, 2FE5DC7F29EDD91D004B9AB4 /* XCRemoteSwiftPackageReference "SpeziOnboarding" */, 2FE5DC8229EDD934004B9AB4 /* XCRemoteSwiftPackageReference "SpeziQuestionnaire" */, 2FE5DC8529EDD950004B9AB4 /* XCRemoteSwiftPackageReference "SpeziScheduler" */, @@ -473,7 +453,6 @@ 2FE5DC8D29EDD980004B9AB4 /* XCRemoteSwiftPackageReference "SpeziViews" */, 2FE5DC9029EDD9C3004B9AB4 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, 2FE5DC9729EDD9D9004B9AB4 /* XCRemoteSwiftPackageReference "XCTestExtensions" */, - 2FE5DC9A29EDD9EF004B9AB4 /* XCRemoteSwiftPackageReference "XCTHealthKit" */, ); productRefGroup = 653A254E283387FE005D4D48 /* Products */; projectDirPath = ""; @@ -549,8 +528,6 @@ 2FE5DCB029EE6107004B9AB4 /* UserView.swift in Sources */, 2FE5DC3929EDD7CA004B9AB4 /* String+ModuleLocalized.swift in Sources */, 2FE5DC3A29EDD7CA004B9AB4 /* Welcome.swift in Sources */, - 2FE5DC3829EDD7CA004B9AB4 /* InterestingModules.swift in Sources */, - 2FE5DC3529EDD7CA004B9AB4 /* Consent.swift in Sources */, 2FE5DC4529EDD7F2004B9AB4 /* Binding+Negate.swift in Sources */, 2FE5DCB229EE6107004B9AB4 /* NAMSLogin.swift in Sources */, 2FC975A82978F11A00BA99FE /* Home.swift in Sources */, @@ -568,7 +545,6 @@ 2F5E32BD297E05EA003432F8 /* NAMSAppDelegate.swift in Sources */, 2FE5DC5229EDD7FA004B9AB4 /* NAMSScheduler.swift in Sources */, 653A2551283387FE005D4D48 /* NAMSApp.swift in Sources */, - 2FE5DC3629EDD7CA004B9AB4 /* HealthKitPermissions.swift in Sources */, 2FE5DC2629EDD38A004B9AB4 /* Contacts.swift in Sources */, 2DC17337BA4FEF5664BC0D10 /* FinishedSetup.swift in Sources */, ); @@ -1123,14 +1099,6 @@ minimumVersion = 0.3.0; }; }; - 2FE5DC7029EDD8D3004B9AB4 /* XCRemoteSwiftPackageReference "SpeziHealthKit" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/StanfordSpezi/SpeziHealthKit.git"; - requirement = { - kind = upToNextMinorVersion; - minimumVersion = 0.2.0; - }; - }; 2FE5DC7329EDD8E6004B9AB4 /* XCRemoteSwiftPackageReference "SpeziFirebase" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/StanfordSpezi/SpeziFirebase.git"; @@ -1139,14 +1107,6 @@ minimumVersion = 0.3.0; }; }; - 2FE5DC7C29EDD907004B9AB4 /* XCRemoteSwiftPackageReference "SpeziHealthKitToFHIRAdapter" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/StanfordSpezi/SpeziHealthKitToFHIRAdapter.git"; - requirement = { - kind = upToNextMinorVersion; - minimumVersion = 0.3.0; - }; - }; 2FE5DC7F29EDD91D004B9AB4 /* XCRemoteSwiftPackageReference "SpeziOnboarding" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/StanfordSpezi/SpeziOnboarding.git"; @@ -1203,14 +1163,6 @@ minimumVersion = 0.4.2; }; }; - 2FE5DC9A29EDD9EF004B9AB4 /* XCRemoteSwiftPackageReference "XCTHealthKit" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/StanfordBDHG/XCTHealthKit.git"; - requirement = { - kind = upToNextMinorVersion; - minimumVersion = 0.3.3; - }; - }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -1244,11 +1196,6 @@ package = 2FE5DC6D29EDD8BF004B9AB4 /* XCRemoteSwiftPackageReference "SpeziFHIRtoFirestoreAdapter" */; productName = SpeziFHIRToFirestoreAdapter; }; - 2FE5DC7129EDD8D3004B9AB4 /* SpeziHealthKit */ = { - isa = XCSwiftPackageProductDependency; - package = 2FE5DC7029EDD8D3004B9AB4 /* XCRemoteSwiftPackageReference "SpeziHealthKit" */; - productName = SpeziHealthKit; - }; 2FE5DC7429EDD8E6004B9AB4 /* SpeziFirebaseAccount */ = { isa = XCSwiftPackageProductDependency; package = 2FE5DC7329EDD8E6004B9AB4 /* XCRemoteSwiftPackageReference "SpeziFirebase" */; @@ -1269,11 +1216,6 @@ package = 2FE5DC7329EDD8E6004B9AB4 /* XCRemoteSwiftPackageReference "SpeziFirebase" */; productName = SpeziFirestorePrefixUserIdAdapter; }; - 2FE5DC7D29EDD907004B9AB4 /* SpeziHealthKitToFHIRAdapter */ = { - isa = XCSwiftPackageProductDependency; - package = 2FE5DC7C29EDD907004B9AB4 /* XCRemoteSwiftPackageReference "SpeziHealthKitToFHIRAdapter" */; - productName = SpeziHealthKitToFHIRAdapter; - }; 2FE5DC8029EDD91D004B9AB4 /* SpeziOnboarding */ = { isa = XCSwiftPackageProductDependency; package = 2FE5DC7F29EDD91D004B9AB4 /* XCRemoteSwiftPackageReference "SpeziOnboarding" */; @@ -1309,11 +1251,6 @@ package = 2FE5DC9729EDD9D9004B9AB4 /* XCRemoteSwiftPackageReference "XCTestExtensions" */; productName = XCTestExtensions; }; - 2FE5DC9B29EDD9EF004B9AB4 /* XCTHealthKit */ = { - isa = XCSwiftPackageProductDependency; - package = 2FE5DC9A29EDD9EF004B9AB4 /* XCRemoteSwiftPackageReference "XCTHealthKit" */; - productName = XCTHealthKit; - }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 653A2545283387FE005D4D48 /* Project object */; diff --git a/NAMS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/NAMS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index cb374c6..e99021d 100644 --- a/NAMS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/NAMS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -72,15 +72,6 @@ "version" : "3.1.1" } }, - { - "identity" : "healthkitonfhir", - "kind" : "remoteSourceControl", - "location" : "https://github.com/StanfordBDHG/HealthKitOnFHIR", - "state" : { - "revision" : "d10f408766264183cd50bb117b99580255520aa3", - "version" : "0.2.3" - } - }, { "identity" : "leveldb", "kind" : "remoteSourceControl", @@ -180,24 +171,6 @@ "version" : "0.3.0" } }, - { - "identity" : "spezihealthkit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/StanfordSpezi/SpeziHealthKit.git", - "state" : { - "revision" : "d03eabcaae2de1e25a626c9a3116dc50f01cdc68", - "version" : "0.2.0" - } - }, - { - "identity" : "spezihealthkittofhiradapter", - "kind" : "remoteSourceControl", - "location" : "https://github.com/StanfordSpezi/SpeziHealthKitToFHIRAdapter.git", - "state" : { - "revision" : "e43f2c05cebcd16a697397721e6a2d72bf418a9c", - "version" : "0.3.0" - } - }, { "identity" : "spezionboarding", "kind" : "remoteSourceControl", @@ -261,15 +234,6 @@ "version" : "0.4.2" } }, - { - "identity" : "xcthealthkit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/StanfordBDHG/XCTHealthKit.git", - "state" : { - "revision" : "19395bbd14a2554e4c9d3fe5cf38aa626c807269", - "version" : "0.3.3" - } - }, { "identity" : "xctruntimeassertions", "kind" : "remoteSourceControl", diff --git a/NAMS/NAMSAppDelegate.swift b/NAMS/NAMSAppDelegate.swift index 4c62b78..17b409a 100644 --- a/NAMS/NAMSAppDelegate.swift +++ b/NAMS/NAMSAppDelegate.swift @@ -14,11 +14,8 @@ import SpeziFirebaseAccount import class FirebaseFirestore.FirestoreSettings import class FirebaseFirestore.MemoryCacheSettings import FirebaseAuth -import HealthKit import SpeziFirestore import SpeziFirestorePrefixUserIdAdapter -import SpeziHealthKit -import SpeziHealthKitToFHIRAdapter import SpeziQuestionnaire import SpeziScheduler import SwiftUI @@ -35,9 +32,6 @@ class NAMSAppDelegate: SpeziAppDelegate { } firestore } - if HKHealthStore.isHealthDataAvailable() { - healthKit - } QuestionnaireDataSource() MockDataStorageProvider() NAMSScheduler() @@ -61,16 +55,4 @@ class NAMSAppDelegate: SpeziAppDelegate { settings: settings ) } - - - private var healthKit: HealthKit { - HealthKit { - CollectSample( - HKQuantityType(.stepCount), - deliverySetting: .anchorQuery(.afterAuthorizationAndApplicationWillLaunch) - ) - } adapter: { - HealthKitToFHIRAdapter() - } - } } diff --git a/NAMS/Onboarding/AccountSetup/UserView.swift b/NAMS/Onboarding/AccountSetup/UserView.swift index 7af1680..8c6faee 100644 --- a/NAMS/Onboarding/AccountSetup/UserView.swift +++ b/NAMS/Onboarding/AccountSetup/UserView.swift @@ -62,8 +62,7 @@ struct UserView: View { #if DEBUG struct SwiftUIView_Previews: PreviewProvider { static var previews: some View { - var userView = UserView() - userView + UserView() .padding() .environmentObject(FirebaseAccountConfiguration(emulatorSettings: (host: "localhost", port: 9099))) .environmentObject(Account(accountServices: [])) diff --git a/NAMS/Onboarding/Consent.swift b/NAMS/Onboarding/Consent.swift deleted file mode 100644 index 94108bf..0000000 --- a/NAMS/Onboarding/Consent.swift +++ /dev/null @@ -1,62 +0,0 @@ -// -// This source file is part of the Neurodevelopment Assessment and Monitoring System (NAMS) project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import SpeziOnboarding -import SwiftUI - - -struct Consent: View { - @Binding private var onboardingSteps: [OnboardingFlow.Step] - - - private var consentDocument: Data { - guard let path = Bundle.main.url(forResource: "ConsentDocument", withExtension: "md"), - let data = try? Data(contentsOf: path) else { - return Data("CONSENT_LOADING_ERROR".moduleLocalized.utf8) - } - return data - } - - var body: some View { - ConsentView( - header: { - OnboardingTitleView( - title: "CONSENT_TITLE".moduleLocalized, - subtitle: "CONSENT_SUBTITLE".moduleLocalized - ) - }, - asyncMarkdown: { - consentDocument - }, - action: { - if !FeatureFlags.disableFirebase { - onboardingSteps.append(.accountSetup) - } else { - onboardingSteps.append(.finished) - } - } - ) - } - - - init(onboardingSteps: Binding<[OnboardingFlow.Step]>) { - self._onboardingSteps = onboardingSteps - } -} - - -#if DEBUG -struct Consent_Previews: PreviewProvider { - @State private static var path: [OnboardingFlow.Step] = [] - - - static var previews: some View { - Consent(onboardingSteps: $path) - } -} -#endif diff --git a/NAMS/Onboarding/HealthKitPermissions.swift b/NAMS/Onboarding/HealthKitPermissions.swift deleted file mode 100644 index 226d199..0000000 --- a/NAMS/Onboarding/HealthKitPermissions.swift +++ /dev/null @@ -1,71 +0,0 @@ -// -// This source file is part of the Neurodevelopment Assessment and Monitoring System (NAMS) project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import SpeziFHIR -import SpeziHealthKit -import SpeziOnboarding -import SwiftUI - - -struct HealthKitPermissions: View { - @EnvironmentObject var healthKitDataSource: HealthKit - @AppStorage(StorageKeys.onboardingFlowComplete) - var completedOnboardingFlow = false - @State var healthKitProcessing = false - - - var body: some View { - OnboardingView( - contentView: { - VStack { - OnboardingTitleView( - title: "HEALTHKIT_PERMISSIONS_TITLE".moduleLocalized, - subtitle: "HEALTHKIT_PERMISSIONS_SUBTITLE".moduleLocalized - ) - Spacer() - Image(systemName: "heart.text.square.fill") - .font(.system(size: 150)) - .foregroundColor(.accentColor) - Text("HEALTHKIT_PERMISSIONS_DESCRIPTION") - .multilineTextAlignment(.center) - .padding(.vertical, 16) - Spacer() - } - }, actionView: { - OnboardingActionsView( - "HEALTHKIT_PERMISSIONS_BUTTON".moduleLocalized, - action: { - do { - healthKitProcessing = true - // HealthKit is not available in the preview simulator. - if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" { - try await _Concurrency.Task.sleep(for: .seconds(5)) - } else { - try await healthKitDataSource.askForAuthorization() - } - } catch { - print("Could not request HealthKit permissions.") - } - completedOnboardingFlow = true - healthKitProcessing = false - } - ) - } - ) - .navigationBarBackButtonHidden(healthKitProcessing) - } -} - - -#if DEBUG -struct HealthKitPermissions_Previews: PreviewProvider { - static var previews: some View { - HealthKitPermissions() - } -} -#endif diff --git a/NAMS/Onboarding/InterestingModules.swift b/NAMS/Onboarding/InterestingModules.swift deleted file mode 100644 index 31c34ed..0000000 --- a/NAMS/Onboarding/InterestingModules.swift +++ /dev/null @@ -1,71 +0,0 @@ -// -// This source file is part of the Neurodevelopment Assessment and Monitoring System (NAMS) project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import SpeziOnboarding -import SwiftUI - - -struct InterestingModules: View { - @Binding private var onboardingSteps: [OnboardingFlow.Step] - - - var body: some View { - SequentialOnboardingView( - title: "INTERESTING_MODULES_TITLE".moduleLocalized, - subtitle: "INTERESTING_MODULES_SUBTITLE".moduleLocalized, - content: [ - .init( - title: "INTERESTING_MODULES_AREA1_TITLE".moduleLocalized, - description: "INTERESTING_MODULES_AREA1_DESCRIPTION".moduleLocalized - ), - .init( - title: "INTERESTING_MODULES_AREA2_TITLE".moduleLocalized, - description: "INTERESTING_MODULES_AREA2_DESCRIPTION".moduleLocalized - ), - .init( - title: "INTERESTING_MODULES_AREA3_TITLE".moduleLocalized, - description: "INTERESTING_MODULES_AREA3_DESCRIPTION".moduleLocalized - ), - .init( - title: "INTERESTING_MODULES_AREA4_TITLE".moduleLocalized, - description: "INTERESTING_MODULES_AREA4_DESCRIPTION".moduleLocalized - ) - ], - actionText: "INTERESTING_MODULES_BUTTON".moduleLocalized, - action: { - onboardingSteps.append(.accountSetup) - - /* - #if targetEnvironment(simulator) && (arch(i386) || arch(x86_64)) - print("PKCanvas view-related views are currently skipped on Intel-based iOS simulators due to a metal bug on the simulator.") - onboardingSteps.append(.accountSetup) - #else - onboardingSteps.append(.consent) - #endif - */ - } - ) - } - - - init(onboardingSteps: Binding<[OnboardingFlow.Step]>) { - self._onboardingSteps = onboardingSteps - } -} - - -#if DEBUG -struct ThingsToKnow_Previews: PreviewProvider { - @State private static var path: [OnboardingFlow.Step] = [] - - - static var previews: some View { - InterestingModules(onboardingSteps: $path) - } -} -#endif From db6e2743a3045d08ce581d67fd26c5d2060f7688 Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Mon, 12 Jun 2023 17:50:02 +0200 Subject: [PATCH 12/13] Adjust changes in test cases --- NAMS.xcodeproj/project.pbxproj | 4 -- NAMSUITests/HealthKitUploadTests.swift | 75 -------------------------- NAMSUITests/OnboardingTests.swift | 54 ++----------------- 3 files changed, 4 insertions(+), 129 deletions(-) delete mode 100644 NAMSUITests/HealthKitUploadTests.swift diff --git a/NAMS.xcodeproj/project.pbxproj b/NAMS.xcodeproj/project.pbxproj index be7d5b2..f2cde38 100644 --- a/NAMS.xcodeproj/project.pbxproj +++ b/NAMS.xcodeproj/project.pbxproj @@ -12,7 +12,6 @@ 2F4E237E2989A2FE0013F3D9 /* OnboardingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4E237D2989A2FE0013F3D9 /* OnboardingTests.swift */; }; 2F4E23832989D51F0013F3D9 /* NAMSTestingSetup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4E23822989D51F0013F3D9 /* NAMSTestingSetup.swift */; }; 2F4E23872989DB360013F3D9 /* ContactsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4E23862989DB360013F3D9 /* ContactsTests.swift */; }; - 2F4E23892989DB400013F3D9 /* HealthKitUploadTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4E23882989DB400013F3D9 /* HealthKitUploadTests.swift */; }; 2F4FC8D729EE69D300BFFE26 /* MockUpload.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F4FC8D629EE69D300BFFE26 /* MockUpload.swift */; }; 2F5E32BD297E05EA003432F8 /* NAMSAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F5E32BC297E05EA003432F8 /* NAMSAppDelegate.swift */; }; 2F6025CB29BBE70F0045459E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 2F6025CA29BBE70F0045459E /* GoogleService-Info.plist */; }; @@ -85,7 +84,6 @@ 2F4E237D2989A2FE0013F3D9 /* OnboardingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingTests.swift; sourceTree = ""; }; 2F4E23822989D51F0013F3D9 /* NAMSTestingSetup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NAMSTestingSetup.swift; sourceTree = ""; }; 2F4E23862989DB360013F3D9 /* ContactsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactsTests.swift; sourceTree = ""; }; - 2F4E23882989DB400013F3D9 /* HealthKitUploadTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthKitUploadTests.swift; sourceTree = ""; }; 2F4FC8D629EE69D300BFFE26 /* MockUpload.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockUpload.swift; sourceTree = ""; }; 2F5E32BC297E05EA003432F8 /* NAMSAppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NAMSAppDelegate.swift; sourceTree = ""; }; 2F6025CA29BBE70F0045459E /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; @@ -317,7 +315,6 @@ 2F4E237D2989A2FE0013F3D9 /* OnboardingTests.swift */, 653A256B28338800005D4D48 /* SchedulerAndQuestionnaireTests.swift */, 2F4E23862989DB360013F3D9 /* ContactsTests.swift */, - 2F4E23882989DB400013F3D9 /* HealthKitUploadTests.swift */, ); path = NAMSUITests; sourceTree = ""; @@ -563,7 +560,6 @@ buildActionMask = 2147483647; files = ( 2F4E23872989DB360013F3D9 /* ContactsTests.swift in Sources */, - 2F4E23892989DB400013F3D9 /* HealthKitUploadTests.swift in Sources */, 2F4E237E2989A2FE0013F3D9 /* OnboardingTests.swift in Sources */, 653A256C28338800005D4D48 /* SchedulerAndQuestionnaireTests.swift in Sources */, ); diff --git a/NAMSUITests/HealthKitUploadTests.swift b/NAMSUITests/HealthKitUploadTests.swift deleted file mode 100644 index bc2ea59..0000000 --- a/NAMSUITests/HealthKitUploadTests.swift +++ /dev/null @@ -1,75 +0,0 @@ -// -// This source file is part of the Neurodevelopment Assessment and Monitoring System (NAMS) project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import XCTest -import XCTestExtensions -import XCTHealthKit - - -class HealthKitUploadTests: XCTestCase { - override func setUpWithError() throws { - throw XCTSkip("HelathKit Tests are currently skipped!") - try super.setUpWithError() - - try disablePasswordAutofill() - - continueAfterFailure = false - - let app = XCUIApplication() - app.launchArguments = ["--showOnboarding"] - app.deleteAndLaunch(withSpringboardAppName: "NAMS") - } - - - func testHealthKitMockUpload() throws { - throw XCTSkip("HelathKit Tests are currently skipped!") - - let app = XCUIApplication() - - try app.conductOnboardingIfNeeded() - - try navigateToMockUpload() - - try assertObservationCellPresent(false) - - try exitAppAndOpenHealth(.steps) - - app.activate() - - sleep(5) - - try navigateToMockUpload() - try assertObservationCellPresent(true, pressIfPresent: true) - try assertObservationCellPresent(true, pressIfPresent: false) - } - - - private func navigateToMockUpload() throws { - let app = XCUIApplication() - - XCTAssertTrue(app.tabBars["Tab Bar"].buttons["Mock Upload"].waitForExistence(timeout: 2)) - app.tabBars["Tab Bar"].buttons["Mock Upload"].tap() - } - - private func assertObservationCellPresent(_ shouldBePresent: Bool, pressIfPresent: Bool = true) throws { - let app = XCUIApplication() - - let observationText = "/Observation/" - let predicate = NSPredicate(format: "label CONTAINS[c] %@", observationText) - - if shouldBePresent { - XCTAssertTrue(app.staticTexts.containing(predicate).firstMatch.waitForExistence(timeout: 2)) - if pressIfPresent { - app.staticTexts.containing(predicate).firstMatch.tap() - XCTAssert(app.navigationBars.buttons["Mock Upload"].waitForExistence(timeout: 2)) - } - } else { - XCTAssertFalse(app.staticTexts.containing(predicate).firstMatch.waitForExistence(timeout: 2)) - } - } -} diff --git a/NAMSUITests/OnboardingTests.swift b/NAMSUITests/OnboardingTests.swift index 683e302..8c465ed 100644 --- a/NAMSUITests/OnboardingTests.swift +++ b/NAMSUITests/OnboardingTests.swift @@ -8,8 +8,6 @@ import XCTest import XCTestExtensions -import XCTHealthKit - class OnboardingTests: XCTestCase { override func setUpWithError() throws { @@ -28,7 +26,7 @@ class OnboardingTests: XCTestCase { func testOnboardingFlow() throws { let app = XCUIApplication() - try app.navigateOnboardingFlow(assertThatHealthKitConsentIsShown: true) + try app.navigateOnboardingFlow() let tabBar = app.tabBars["Tab Bar"] XCTAssertTrue(tabBar.buttons["Schedule"].waitForExistence(timeout: 2)) @@ -40,19 +38,14 @@ class OnboardingTests: XCTestCase { extension XCUIApplication { func conductOnboardingIfNeeded() throws { - if self.staticTexts["Spezi\nNeurodevelopment Assessment and Monitoring System (NAMS)"].waitForExistence(timeout: 5) { - try navigateOnboardingFlow(assertThatHealthKitConsentIsShown: false) + if self.staticTexts["Neurodevelopment Assessment and Monitoring System (NAMS)"].waitForExistence(timeout: 5) { + try navigateOnboardingFlow() } } - func navigateOnboardingFlow(assertThatHealthKitConsentIsShown: Bool = true) throws { + func navigateOnboardingFlow() throws { try navigateOnboardingFlowWelcome() - // try navigateOnboardingFlowInterestingModules() - // if staticTexts["Consent Example"].waitForExistence(timeout: 5) { - // try navigateOnboardingFlowConsent() - // } try navigateOnboardingAccount() - // try navigateOnboardingFlowHealthKitAccess(assertThatHealthKitConsentIsShown: assertThatHealthKitConsentIsShown) try navigateFinishedSetup() } @@ -64,36 +57,6 @@ extension XCUIApplication { continueButton.tap() } - private func navigateOnboardingFlowInterestingModules() throws { - XCTAssertTrue(staticTexts["Interesting Modules"].waitForExistence(timeout: 2)) - - for _ in 1..<4 { - XCTAssertTrue(buttons["Continue"].waitForExistence(timeout: 2)) - buttons["Continue"].tap() - } - - XCTAssertTrue(buttons["Continue"].waitForExistence(timeout: 2)) - buttons["Continue"].tap() - } - - private func navigateOnboardingFlowConsent() throws { - XCTAssertTrue(staticTexts["Consent Example"].waitForExistence(timeout: 2)) - - XCTAssertTrue(staticTexts["First Name"].waitForExistence(timeout: 2)) - try textFields["Enter your first name ..."].enter(value: "Leland") - textFields["Enter your first name ..."].typeText("\n") - - XCTAssertTrue(staticTexts["Last Name"].waitForExistence(timeout: 2)) - try textFields["Enter your last name ..."].enter(value: "Stanford") - textFields["Enter your last name ..."].typeText("\n") - - XCTAssertTrue(staticTexts["Leland Stanford"].waitForExistence(timeout: 2)) - staticTexts["Leland Stanford"].firstMatch.swipeUp() - - XCTAssertTrue(buttons["I Consent"].waitForExistence(timeout: 2)) - buttons["I Consent"].tap() - } - private func navigateOnboardingAccount() throws { XCTAssertTrue(staticTexts["Your Account"].waitForExistence(timeout: 2)) @@ -157,13 +120,4 @@ extension XCUIApplication { XCTAssertTrue(startButton.waitForExistence(timeout: 2)) startButton.tap() } - - private func navigateOnboardingFlowHealthKitAccess(assertThatHealthKitConsentIsShown: Bool = true) throws { - XCTAssertTrue(staticTexts["HealthKit Access"].waitForExistence(timeout: 2)) - - XCTAssertTrue(buttons["Grant Access"].waitForExistence(timeout: 2)) - buttons["Grant Access"].tap() - - try handleHealthKitAuthorization() - } } From 0264ddfa102af64956eaf76c62befd0c24df22ad Mon Sep 17 00:00:00 2001 From: Andreas Bauer Date: Mon, 12 Jun 2023 18:03:25 +0200 Subject: [PATCH 13/13] Minimal change to retrigger CI and maybe fix CodeCov upload issues? --- NAMS/Onboarding/Welcome.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/NAMS/Onboarding/Welcome.swift b/NAMS/Onboarding/Welcome.swift index 76da48d..d063c78 100644 --- a/NAMS/Onboarding/Welcome.swift +++ b/NAMS/Onboarding/Welcome.swift @@ -9,7 +9,6 @@ import SpeziOnboarding import SwiftUI - struct Welcome: View { @Binding private var onboardingSteps: [OnboardingFlow.Step]