diff --git a/Beiwe.xcodeproj/project.pbxproj b/Beiwe.xcodeproj/project.pbxproj index 55cb6d8..2fccd39 100644 --- a/Beiwe.xcodeproj/project.pbxproj +++ b/Beiwe.xcodeproj/project.pbxproj @@ -879,7 +879,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2024.21; + CURRENT_PROJECT_VERSION = 2024.22; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 6M52R5C7FT; ENABLE_BITCODE = NO; @@ -888,7 +888,7 @@ INFOPLIST_PREPROCESS = NO; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MARKETING_VERSION = 2.5; + MARKETING_VERSION = 2.5.1; PRODUCT_BUNDLE_IDENTIFIER = harvard.lab.onnela.beiwe.ios; PRODUCT_NAME = Beiwe2; PROVISIONING_PROFILE = ""; @@ -979,7 +979,7 @@ CODE_SIGN_ENTITLEMENTS = Beiwe/Beiwe2Release2.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2024.21; + CURRENT_PROJECT_VERSION = 2024.22; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 6M52R5C7FT; ENABLE_BITCODE = NO; @@ -988,7 +988,7 @@ INFOPLIST_PREPROCESS = NO; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MARKETING_VERSION = 2.5; + MARKETING_VERSION = 2.5.1; PRODUCT_BUNDLE_IDENTIFIER = harvard.lab.onnela.beiwe.ios; PRODUCT_NAME = Beiwe2; PROVISIONING_PROFILE = ""; @@ -1146,7 +1146,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2024.21; + CURRENT_PROJECT_VERSION = 2024.22; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 6M52R5C7FT; ENABLE_BITCODE = NO; @@ -1155,7 +1155,7 @@ INFOPLIST_PREPROCESS = NO; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MARKETING_VERSION = 2.5; + MARKETING_VERSION = 2.5.1; PRODUCT_BUNDLE_IDENTIFIER = lab.onnela.beiwe.ios; PRODUCT_NAME = Beiwe; PROVISIONING_PROFILE = ""; @@ -1184,7 +1184,7 @@ CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Onnela Lab LLC (6M52R5C7FT)"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 2024.21; + CURRENT_PROJECT_VERSION = 2024.22; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 6M52R5C7FT; ENABLE_BITCODE = NO; @@ -1193,7 +1193,7 @@ INFOPLIST_PREPROCESS = NO; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MARKETING_VERSION = 2.5; + MARKETING_VERSION = 2.5.1; PRODUCT_BUNDLE_IDENTIFIER = lab.onnela.beiwe.ios; PRODUCT_NAME = Beiwe; PROVISIONING_PROFILE = ""; diff --git a/Beiwe/API/ApiManager.swift b/Beiwe/API/ApiManager.swift index 54c76c2..07ae877 100644 --- a/Beiwe/API/ApiManager.swift +++ b/Beiwe/API/ApiManager.swift @@ -14,7 +14,11 @@ enum ApiErrors: Error { case fileNotFound } -/// One(?) of the request types... no clue how this works yet, but mappables magically convert json +/// This is what we ended up using for our post requests after the promisekit purge, I thought it +/// was part of Alamofire. It isn't. It just takes the output of the request and sticks it on a +/// .body property. Complete garbage intermidiate object. +/// Fixme: kill this class, why are we even using a mappable that's insane. Call the correct +/// Mappable that you need on the body output of the api requests explicitly. struct BodyResponse: Mappable { var body: String? diff --git a/Beiwe/AppDelegate.swift b/Beiwe/AppDelegate.swift index af9e5fc..6cb0b32 100644 --- a/Beiwe/AppDelegate.swift +++ b/Beiwe/AppDelegate.swift @@ -61,9 +61,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate return StudyManager.sharedInstance.currentStudy } - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////// APPLICATION SETUP //////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////// APPLICATION SETUP //////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// /// The AppDelegate started function func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { @@ -94,7 +94,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate return true } - // this is currently literally just being tested because I don't know what it does but apple has documentation about it and the BGTasks are completely unreliable right now. + /// Target(?) for background app refresh https://developer.apple.com/documentation/uikit/uiapplication/1623031-beginbackgroundtask + // """ A handler to be called shortly before the app’s remaining background time + // reaches 0. Use this handler to clean up and mark the end of the background task. + // Failure to end the task explicitly will result in the termination of the app. + // The system calls the handler synchronously on the main thread, blocking the + // app’s suspension momentarily. """ func beginBackgroundTask(withName taskName: String?, expirationHandler handler: (() -> Void)? = nil) -> UIBackgroundTaskIdentifier { StudyManager.sharedInstance.heartbeat("beginBackgroundTask") return UIBackgroundTaskIdentifier(rawValue: 0) @@ -231,7 +236,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate @unknown default: "unknown: '\(UIApplication.shared.backgroundRefreshStatus.rawValue)'" } } - + // print("UIApplication.shared.backgroundTimeRemaining:", UIApplication.shared.backgroundTimeRemaining) updateBackgroundTasksCount() BACKGROUND_DEVICE_INFO_QUEUE.asyncAfter(deadline: .now() + 60, execute: self.deviceInfoUpdateLoop) @@ -305,9 +310,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate return false } - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////// APPLICATION WILL X /////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////// APPLICATION WILL X ////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// func applicationWillEnterForeground(_ application: UIApplication) { print("applicationWillEnterForeground") @@ -369,9 +374,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate print("applicationWillResignActive") } - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////// APPLICATION DID X //////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////// APPLICATION DID X ////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. @@ -414,9 +419,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate AppEventManager.sharedInstance.logAppEvent(event: "locked", msg: "Phone/keystore locked") } - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////// PERMISSIONS ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////// PERMISSIONS ////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// /// this function gets called when CLAuthorization status changes func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { @@ -446,9 +451,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate } } - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////// REAL NOTIFICATION CODE /////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////// REAL NOTIFICATION CODE ///////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("Failed to register for notifications: \(error.localizedDescription)") @@ -518,7 +523,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate // return if nothing found guard let surveyIdsString = messageInfo["survey_ids"] else { print("no surveyIds found, checking for new surveys anyway.") - StudyManager.sharedInstance.downloadSurveys(surveyIds: []) + StudyManager.sharedInstance.checkForNewSurveys(surveyIds: []) return } @@ -529,15 +534,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate // downloadSurveys calls setActiveSurveys, even if it errors/fails. We always want to download the most recent survey information. // (old versions of the backend don't supply the sent_time key) if let sentTimeString = messageInfo["sent_time"] as! String? { - StudyManager.sharedInstance.downloadSurveys(surveyIds: surveyIds, sentTime: isoStringToTimeInterval(timeString: sentTimeString)) + StudyManager.sharedInstance.checkForNewSurveys(surveyIds: surveyIds, sentTime: isoStringToTimeInterval(timeString: sentTimeString)) } else { - StudyManager.sharedInstance.downloadSurveys(surveyIds: surveyIds) + StudyManager.sharedInstance.checkForNewSurveys(surveyIds: surveyIds) } } - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////// MISC BEIWE STUFF ///////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////// MISC BEIWE STUFF /////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// // converts json string to an array of strings func jsonToSurveyIdArray(json: String) -> [String] { @@ -554,9 +559,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate return surveyIds } - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////// Firebase Stuff /////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////// Firebase Stuff //////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// func firebaseLoop() { // The app cannot register with firebase until it gets a token, which only occurs at registration time, and it needs access to the appDelegate. @@ -663,9 +668,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate } } - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////// UI STUFF /////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////// STUFF ////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// func initializeUI() { // set up colors for researchkit, set the launch screen view. @@ -719,9 +724,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate } } - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////// CRASHLYTICS STUFF //////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////// CRASHLYTICS STUFF //////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// // func setupCrashLytics() { // Fabric.with([Crashlytics.self]) @@ -752,9 +757,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate // Crashlytics.sharedInstance().crash() // } - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////// SENTRY STUFF //////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////// SENTRY STUFF ////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////////////////// func setupSentry() { // loads sentry key, prints an error if it doesn't work. diff --git a/Beiwe/Controllers/AudioQuestionViewController.swift b/Beiwe/Controllers/AudioQuestionViewController.swift index 1c5ebc3..58c4f71 100644 --- a/Beiwe/Controllers/AudioQuestionViewController.swift +++ b/Beiwe/Controllers/AudioQuestionViewController.swift @@ -262,7 +262,6 @@ class AudioQuestionViewController: UIViewController, AVAudioRecorderDelegate, AV do { self.saveEncryptedAudio() self.activeSurvey.isComplete = true - StudyManager.sharedInstance.cleanupSurvey(self.activeSurvey) StudyManager.sharedInstance.updateActiveSurveys(true) HUD.flash(.success, delay: 0.5) self.cleanupAndDismiss() diff --git a/Beiwe/Managers/DataStorageManager.swift b/Beiwe/Managers/DataStorageManager.swift index b207f04..b366d09 100644 --- a/Beiwe/Managers/DataStorageManager.swift +++ b/Beiwe/Managers/DataStorageManager.swift @@ -365,9 +365,9 @@ class DataStorageManager { // } } -////////////////////////////////////////////////////// Data Storage /////////////////////////////////////////////////////// -////////////////////////////////////////////////////// Data Storage /////////////////////////////////////////////////////// -////////////////////////////////////////////////////// Data Storage /////////////////////////////////////////////////////// +///////////////////////////////////////////// Data Storage ///////////////////////////////////////// +///////////////////////////////////////////// Data Storage ///////////////////////////////////////// +///////////////////////////////////////////// Data Storage ///////////////////////////////////////// class DataStorage { // participant info (to be factored out)