diff --git a/LifeSpace.xcodeproj/project.pbxproj b/LifeSpace.xcodeproj/project.pbxproj index 6f457d0..365238a 100644 --- a/LifeSpace.xcodeproj/project.pbxproj +++ b/LifeSpace.xcodeproj/project.pbxproj @@ -820,7 +820,7 @@ CODE_SIGN_ENTITLEMENTS = "LifeSpace/Supporting Files/LifeSpace.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = ""; ENABLE_PREVIEWS = YES; @@ -1022,7 +1022,7 @@ CODE_SIGN_ENTITLEMENTS = "LifeSpace/Supporting Files/LifeSpace.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = ""; ENABLE_PREVIEWS = YES; @@ -1070,7 +1070,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = ""; diff --git a/LifeSpace/Account/AccountSheet.swift b/LifeSpace/Account/AccountSheet.swift index f8cae1a..2aea5d8 100644 --- a/LifeSpace/Account/AccountSheet.swift +++ b/LifeSpace/Account/AccountSheet.swift @@ -49,6 +49,8 @@ struct AccountSheet: View { @AppStorage(StorageKeys.studyID) var studyID = "unknownStudyID" @AppStorage(StorageKeys.trackingPreference) private var trackingOn = true + @AppStorage(StorageKeys.lastSurveyTransmissionDate) private var lastSurveyTransmissionDate = "Not set" + @AppStorage(StorageKeys.lastLocationTransmissionDate) private var lastLocationTransmissionDate = "Not set" var body: some View { NavigationStack { @@ -108,6 +110,12 @@ struct AccountSheet: View { Section(header: Text("DEBUG_SECTION")) { logExportButton } + Section(header: Text("LAST_SURVEY_TRANSMISSION_SECTION")) { + Text(lastSurveyTransmissionDate) + } + Section(header: Text("LAST_LOCATION_TRANSMISSION_SECTION")) { + Text(lastLocationTransmissionDate) + } } } } @@ -183,7 +191,6 @@ struct AccountSheet: View { } } - private func getDocumentURL(for fileName: String) -> URL? { guard let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return nil diff --git a/LifeSpace/Resources/Localizable.xcstrings b/LifeSpace/Resources/Localizable.xcstrings index b2e6671..1b780ba 100644 --- a/LifeSpace/Resources/Localizable.xcstrings +++ b/LifeSpace/Resources/Localizable.xcstrings @@ -325,6 +325,26 @@ } } }, + "LAST_LOCATION_TRANSMISSION_SECTION" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Last Successful Location Data Transmission" + } + } + } + }, + "LAST_SURVEY_TRANSMISSION_SECTION" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Last Successful Survey Transmission" + } + } + } + }, "LOADING_LOGS" : { "localizations" : { "en" : { diff --git a/LifeSpace/SharedContext/StorageKeys.swift b/LifeSpace/SharedContext/StorageKeys.swift index 2ac4d19..5bdbe07 100644 --- a/LifeSpace/SharedContext/StorageKeys.swift +++ b/LifeSpace/SharedContext/StorageKeys.swift @@ -8,16 +8,12 @@ /// Constants shared across the Spezi Teamplate Application to access storage information including the `AppStorage` and `SceneStorage` 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" /// A `String` containing the user's study ID. static let studyID = "studyID" - - - // MARK: - Home /// A `String` containing the currently selected home tab. static let homeTabSelection = "home.tabselection" /// A `Bool` representing whether the user has chosen to enable or disable location tracking. @@ -26,4 +22,8 @@ enum StorageKeys { static let lastSurveyDate = "lastSurveyDate" /// A `Bool` representing whether location permissions have been previously requested. static let isFirstLocationRequest = "isFirstLocationRequest" + /// `Date`s containing the timestamp of the last successful transmission for surveys. + static let lastSurveyTransmissionDate = "lastSurveyTransmissionDate" + /// `Date`s containing the timestamp of the last successful transmission for location data. + static let lastLocationTransmissionDate = "lastLocationTransmissionDate" } diff --git a/LifeSpaceStandard.swift b/LifeSpaceStandard.swift index c9d1fd2..5c724f7 100644 --- a/LifeSpaceStandard.swift +++ b/LifeSpaceStandard.swift @@ -125,6 +125,11 @@ actor LifeSpaceStandard: Standard, .collection(Constants.locationDataCollectionName) .document(UUID().uuidString) .setData(from: dataPoint) + + // Store a timestamp of this transmission for debugging purposes + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" + UserDefaults.standard.set(formatter.string(from: Date.now), forKey: StorageKeys.lastLocationTransmissionDate) } func fetchLocations(on date: Date = Date()) async throws -> [CLLocationCoordinate2D] { @@ -183,6 +188,11 @@ actor LifeSpaceStandard: Standard, ], merge: true ) + + // Store a timestamp of this transmission for debugging purposes + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" + UserDefaults.standard.set(formatter.string(from: Date.now), forKey: StorageKeys.lastSurveyTransmissionDate) } func getLatestSurveyDate() async -> String { @@ -201,8 +211,8 @@ actor LifeSpaceStandard: Standard, private func healthKitDocument(id uuid: UUID) async throws -> DocumentReference { try await configuration.userDocumentReference - .collection(Constants.healthKitCollectionName) // Add all HealthKit sources in a /HealthKit collection. - .document(uuid.uuidString) // Set the document identifier to the UUID of the document. + .collection(Constants.healthKitCollectionName) + .document(uuid.uuidString) } func deletedAccount() async throws {