From 920b9752946dac40898adc43689a40bb526f450e Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Tue, 27 Dec 2022 16:47:41 -0500 Subject: [PATCH 1/6] expose method to report the final load operation source --- MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.h | 1 + MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.h b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.h index ab87548..1a9f80a 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.h +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.h @@ -22,6 +22,7 @@ @property (nullable, strong, nonatomic) MVMCoreLoadObject *loadObject; @property (nullable, strong, nonatomic) NSDictionary *dataForPage; @property (nullable, strong, nonatomic) DelegateObject *delegateObject; +@property (nullable, nonatomic, readonly) NSString *finalLoadSource; @property (nonatomic) BOOL backgroundLoad; @property (nonatomic, getter=areDependenciesAdded) BOOL dependenciesAdded; diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m index d48d53f..48f104c 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m @@ -77,6 +77,10 @@ [super start]; } +- (NSString *)finalLoadSource { + return _sessionTask.currentRequest.URL.absoluteString; +} + - (void)markAsFinished { // stop any loading animation we may have started From aa1be3f1c59ca0cf13a3c73dfba5bd543ccae0ea Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Wed, 28 Dec 2022 10:23:10 -0500 Subject: [PATCH 2/6] Fix isAppInSession and appEnteredForeground collision. Fix FaceId session timer restart skip. Encapsulate timeTimerStarted referenceDate. --- .../Session/MVMCoreSessionTimeHandler.h | 37 +++--- .../Session/MVMCoreSessionTimeHandler.m | 107 ++++++++++-------- 2 files changed, 79 insertions(+), 65 deletions(-) diff --git a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.h b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.h index d31ae62..99ee577 100644 --- a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.h +++ b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.h @@ -13,50 +13,57 @@ @interface MVMCoreSessionTimeHandler : NSObject -// The time that we started the last session timer. -@property (assign, nonatomic, readonly) NSTimeInterval timeTimerStarted; +/// The number of seconds ago that we started the last session timer. Distant past if it wasn't started. +@property (nonatomic, readonly) NSTimeInterval timeSinceStart; -// Keeps track of if the session is currently being timed. Used for entering from the background. +/// The number of seconds remaining until a warning will occur. +@property (nonatomic, readonly) NSTimeInterval remainingTimeUntilWarning; + +/// The number of seconds remaining until a timeout will occur. +@property (nonatomic, readonly) NSTimeInterval remainingTimeUntiTimeout; + + +/// Keeps track of if the session is currently being timed. Used for entering from the background. @property (assign, nonatomic, readonly) BOOL sessionBeingTimed; -// Keeps track of if the session has already timed out. +/// Keeps track of if the session has already timed out. @property (assign, nonatomic, readonly) BOOL sessionTimedOut; #pragma mark - functions to override -// Can override to provide a time until the warning shows in seconds. Set to 0 if there should be no warning. Default is 0 +/// Can override to provide a time until the warning shows in seconds. Set to 0 if there should be no warning. Default is 0 - (NSTimeInterval)timeUntilWarning; -// Can override to provide a time until the timeout happens in seconds. If there is a warning, then this value is used after the warning happens. Set to 0 if there should be no timeout. Default is 0. +/// Can override to provide a time until the timeout happens in seconds. If there is a warning, then this value is used after the warning happens. Set to 0 if there should be no timeout. Default is 0. - (NSTimeInterval)timeUntilTimeout; -// Starts the timeout timer. Override to handle what happens on timeout warning. Should call super if want the timeout timer going. +/// Starts the timeout timer. Override to handle what happens on timeout warning. Should call super if want the timeout timer going. - (void)sessionTimeoutWarning NS_REQUIRES_SUPER; -// Called when the session has timed out. Override to handle what happens on timeout. Should call super. Can be called to force timeout... should never need to call unless simulating timout. +/// Called when the session has timed out. Override to handle what happens on timeout. Should call super. Can be called to force timeout... should never need to call unless simulating timout. - (void)sessionTimeout:(BOOL)whileInBackground NS_REQUIRES_SUPER; -// Keeps the session alive. A boolean for if we should show the alert if there is an error. Does nothing by default. Can override to do something. +/// Keeps the session alive. A boolean for if we should show the alert if there is an error. Does nothing by default. Can override to do something. - (void)sendKeepAliveToServer:(BOOL)notifyUserIfError; -// Invalidates the server session and then calls the completion handler. Error may or may not populate. By default this only calls the completion handler, override to invalidate your server session as you see fit then call completion. +/// Invalidates the server session and then calls the completion handler. Error may or may not populate. By default this only calls the completion handler, override to invalidate your server session as you see fit then call completion. - (void)invalidateSession:(void (^ __nullable)(MVMCoreErrorObject * _Nullable error))completion; #pragma mark - Session timer functions -// Returns the shared instance of this singleton +/// Returns the shared instance of this singleton + (nullable instancetype)sharedSessionHandler; -// Starts the session timer. Should be called after every response from the server. Happens on the main thread. +/// Starts the session timer. Should be called after every response from the server. Happens on the main thread. - (void)startSessionTimer; -// Should only be used in rare occassions, like on the original wifi screen. +/// Completely stop the session timer. Should only be used in rare occassions, like on the original wifi screen. - (void)stopSessionTimer; -// Returns whether the app is in session. +/// Returns whether the app is in session. - (BOOL)isAppInSession; -// Resets everything. +/// Resets everything. - (void)resetState; @end diff --git a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m index f0bf1b5..be90025 100644 --- a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m +++ b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m @@ -24,22 +24,22 @@ @property (strong, nonatomic) NSTimer *sessionWarningTimer; @property (strong, nonatomic) NSTimer *sessionTimer; -// The time that we started the last session timer. +/// The time that we started the last session timer. @property (assign, nonatomic, readwrite) NSTimeInterval timeTimerStarted; -// Keeps track of if the session is currently being timed. Used for entering from the background. +/// Keeps track of if the session is currently being timed. Used for entering from the background. @property (assign, nonatomic, readwrite) BOOL sessionBeingTimed; -// Keeps track of if the session has already timed out. +/// Keeps track of if the session has already timed out. @property (assign, nonatomic, readwrite) BOOL sessionTimedOut; @property (assign, nonatomic) NSTimeInterval secondsUntilWarning; @property (assign, nonatomic) NSTimeInterval secondsUntilTimeout; -// Should be called when the app enters the background. +/// Should be called when the app enters the background. - (void)appEnteredBackground; -// Should be called when the app enters the foreground. +/// Should be called when the app enters the foreground. - (void)appEnteredForeground; @end @@ -55,6 +55,7 @@ // Adds notifications for if the app entered the background/foreground. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appEnteredBackground) name:UIApplicationDidEnterBackgroundNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appEnteredForeground) name:UIApplicationWillEnterForegroundNotification object:nil]; + [self resetStartTime]; } return self; } @@ -85,6 +86,28 @@ - (void)sendKeepAliveToServer:(BOOL)notifyUserIfError { } +#pragma mark - State + +- (void)markStartTime { + self.timeTimerStarted = [NSDate timeIntervalSinceReferenceDate]; +} + +- (void)resetStartTime { + self.timeTimerStarted = [[NSDate distantPast] timeIntervalSinceReferenceDate]; +} + +- (NSTimeInterval)timeSinceStart { + return [NSDate timeIntervalSinceReferenceDate] - self.timeTimerStarted; +} + +- (NSTimeInterval)remainingTimeUntilWarning { + return self.secondsUntilWarning - self.timeSinceStart; +} + +- (NSTimeInterval)remainingTimeUntiTimeout { + return self.secondsUntilTimeout - self.timeSinceStart; +} + #pragma mark - Session timer functions - (void)startSessionTimer { @@ -97,22 +120,34 @@ self.secondsUntilWarning = [self timeUntilWarning]; self.secondsUntilTimeout = [self timeUntilTimeout]; + if (!fequal(0, self.secondsUntilTimeout)) { self.sessionBeingTimed = YES; - self.timeTimerStarted = [NSDate timeIntervalSinceReferenceDate]; - } - - // Only start physical timer if active, otherwise will begin once entering foreground. - if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive && !fequal(0, self.secondsUntilTimeout)) { - if (!fequal(0, self.secondsUntilWarning)) { - self.sessionWarningTimer = [NSTimer scheduledTimerWithTimeInterval:self.secondsUntilWarning target:self selector:@selector(sessionTimeoutWarning) userInfo:nil repeats:NO]; + [self markStartTime]; + + // Only start physical timer if active, otherwise will begin once entering foreground. FaceId prompt is considered UIApplicationStateInactive. + if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) { + [self resumeSessionTimer]; } - self.sessionTimer = [NSTimer scheduledTimerWithTimeInterval:self.secondsUntilTimeout target:self selector:@selector(sessionTimeout:) userInfo:nil repeats:NO]; } } }); } +/// Resume the session timers if they are stopped. +- (void)resumeSessionTimer { + dispatch_async(dispatch_get_main_queue(), ^(void) { + if (!fequal(0, self.secondsUntilWarning) && ![self.sessionWarningTimer isValid]) { + self.sessionWarningTimer = [NSTimer scheduledTimerWithTimeInterval:[self remainingTimeUntilWarning] target:self selector:@selector(sessionTimeoutWarning) userInfo:nil repeats:NO]; + MVMCoreLog(@"Session warning will fire at: %@", self.sessionWarningTimer.fireDate); + } + if (!fequal(0, self.secondsUntilTimeout) && ![self.sessionTimer isValid]) { + self.sessionTimer = [NSTimer scheduledTimerWithTimeInterval:[self remainingTimeUntiTimeout] target:self selector:@selector(sessionTimeout:) userInfo:nil repeats:NO]; + MVMCoreLog(@"Session timeout will fire at: %@", self.sessionTimer.fireDate); + } + }); +} + - (void)stopSessionTimer { // nil timer, session no longer timed. @@ -137,31 +172,7 @@ } - (void)appEnteredForeground { - - if (self.sessionBeingTimed || self.sessionTimedOut) { - - NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate]; - if ((!fequal(0, self.secondsUntilWarning) && now > self.timeTimerStarted + self.secondsUntilWarning) || (!fequal(0, self.secondsUntilTimeout) && now > self.timeTimerStarted + self.secondsUntilTimeout)) { - - // Timeout if we are passed the warning. - [self sessionTimeout:YES]; - } else { - if (!fequal(0, self.secondsUntilWarning)) { - - // Restart the warning timer! - NSTimeInterval timeLeftTillWarning = self.timeTimerStarted + self.secondsUntilWarning - now; - [self.sessionWarningTimer invalidate]; - self.sessionWarningTimer = [NSTimer scheduledTimerWithTimeInterval:timeLeftTillWarning target:self selector:@selector(sessionTimeoutWarning) userInfo:nil repeats:NO]; - } - if (!fequal(0, self.secondsUntilTimeout)) { - - // Restart the timeout timer! - NSTimeInterval timeLeftTillTimeout = self.timeTimerStarted + self.secondsUntilTimeout - now; - [self.sessionTimer invalidate]; - self.sessionTimer = [NSTimer scheduledTimerWithTimeInterval:timeLeftTillTimeout target:self selector:@selector(sessionTimeout:) userInfo:nil repeats:NO]; - } - } - } + [self revalidateSessionTimestamp]; } - (void)invalidateSession:(void (^ __nullable)(MVMCoreErrorObject * _Nullable error))completion { @@ -170,18 +181,14 @@ // Checks to make sure session is still valid and that the timer is running. - (void)revalidateSessionTimestamp { - if (self.sessionBeingTimed && !self.sessionTimedOut) { - - NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate]; - if ((!fequal(0, self.secondsUntilWarning) && now > self.timeTimerStarted + self.secondsUntilWarning) || (!fequal(0, self.secondsUntilTimeout) && now > self.timeTimerStarted + self.secondsUntilTimeout)) { - self.sessionTimedOut = YES; - [self.sessionWarningTimer invalidate]; - self.sessionWarningTimer = nil; - [self.sessionTimer invalidate]; - self.sessionTimer = nil; - } else if (![self.sessionTimer isValid]) { - // Restart the session timer! - [self startSessionTimer]; + if (self.sessionBeingTimed || self.sessionTimedOut) { + NSTimeInterval timeSinceStart = [self timeSinceStart]; + if ((!fequal(0, self.secondsUntilWarning) && timeSinceStart > self.secondsUntilWarning) || (!fequal(0, self.secondsUntilTimeout) && timeSinceStart > self.secondsUntilTimeout)) { + + // Timeout if we are passed the warning. + [self sessionTimeout:YES]; + } else { + [self resumeSessionTimer]; } } } From c7bfda216a79c04689894754c16935bc9a41165e Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Wed, 28 Dec 2022 10:54:31 -0500 Subject: [PATCH 3/6] Trigger a keep alive attempt when returning from background. --- MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m index be90025..0ab40c8 100644 --- a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m +++ b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m @@ -172,7 +172,9 @@ } - (void)appEnteredForeground { + // Revalidate first to check if we should be in the timeout state. [self revalidateSessionTimestamp]; + [self sendKeepAliveToServer:NO]; } - (void)invalidateSession:(void (^ __nullable)(MVMCoreErrorObject * _Nullable error))completion { From 80512a0b8aadd9f3bd3f1b56123320bd29842147 Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Wed, 28 Dec 2022 11:02:02 -0500 Subject: [PATCH 4/6] Shift app background check to resumeSessionTimer to make isAppInSession and revalidateSessionTimestamp background safe. --- MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m index 0ab40c8..84dbc0f 100644 --- a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m +++ b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m @@ -124,11 +124,7 @@ if (!fequal(0, self.secondsUntilTimeout)) { self.sessionBeingTimed = YES; [self markStartTime]; - - // Only start physical timer if active, otherwise will begin once entering foreground. FaceId prompt is considered UIApplicationStateInactive. - if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) { - [self resumeSessionTimer]; - } + [self resumeSessionTimer]; } } }); @@ -137,6 +133,11 @@ /// Resume the session timers if they are stopped. - (void)resumeSessionTimer { dispatch_async(dispatch_get_main_queue(), ^(void) { + // Only start physical timer if active, otherwise will begin once entering foreground. FaceId prompt is considered UIApplicationStateInactive. + if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) { + return; + } + if (!fequal(0, self.secondsUntilWarning) && ![self.sessionWarningTimer isValid]) { self.sessionWarningTimer = [NSTimer scheduledTimerWithTimeInterval:[self remainingTimeUntilWarning] target:self selector:@selector(sessionTimeoutWarning) userInfo:nil repeats:NO]; MVMCoreLog(@"Session warning will fire at: %@", self.sessionWarningTimer.fireDate); From 16d169c46c4f9816f45da76ce552d958b73f0286 Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Fri, 13 Jan 2023 18:57:23 -0500 Subject: [PATCH 5/6] Code review suggestion to use default values. Bug fix for warning track timeouts from the background. --- .../Session/MVMCoreSessionTimeHandler.h | 7 ++- .../Session/MVMCoreSessionTimeHandler.m | 47 ++++++++++++++----- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.h b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.h index 99ee577..cb4db62 100644 --- a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.h +++ b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.h @@ -13,16 +13,15 @@ @interface MVMCoreSessionTimeHandler : NSObject -/// The number of seconds ago that we started the last session timer. Distant past if it wasn't started. +/// The number of seconds ago that we started the last session timer. A value of -1 will be returned for sessions not started. @property (nonatomic, readonly) NSTimeInterval timeSinceStart; -/// The number of seconds remaining until a warning will occur. +/// The number of seconds remaining until a warning will occur. A value of 0 will be returned for sessions not started or warning tracking is not enabled. @property (nonatomic, readonly) NSTimeInterval remainingTimeUntilWarning; -/// The number of seconds remaining until a timeout will occur. +/// The number of seconds remaining until a timeout will occur. A value of 0 will be returned for sessions not started or timeout tracking is not enabled. @property (nonatomic, readonly) NSTimeInterval remainingTimeUntiTimeout; - /// Keeps track of if the session is currently being timed. Used for entering from the background. @property (assign, nonatomic, readonly) BOOL sessionBeingTimed; diff --git a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m index 84dbc0f..191c3a8 100644 --- a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m +++ b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m @@ -93,18 +93,35 @@ } - (void)resetStartTime { - self.timeTimerStarted = [[NSDate distantPast] timeIntervalSinceReferenceDate]; + self.timeTimerStarted = -1; } - (NSTimeInterval)timeSinceStart { + if (self.timeTimerStarted < 0) { + return -1; + } return [NSDate timeIntervalSinceReferenceDate] - self.timeTimerStarted; } +- (BOOL)isWarningEnabled { + return !fequal(0, self.secondsUntilWarning); +} + +- (BOOL)isTimeoutEnabled { + return !fequal(0, self.secondsUntilTimeout); +} + - (NSTimeInterval)remainingTimeUntilWarning { + if (self.timeTimerStarted < 0 || ![self isTimeoutEnabled]) { + return 0; + } return self.secondsUntilWarning - self.timeSinceStart; } - (NSTimeInterval)remainingTimeUntiTimeout { + if (self.timeTimerStarted < 0 || ![self isTimeoutEnabled]) { + return 0; + } return self.secondsUntilTimeout - self.timeSinceStart; } @@ -121,7 +138,7 @@ self.secondsUntilWarning = [self timeUntilWarning]; self.secondsUntilTimeout = [self timeUntilTimeout]; - if (!fequal(0, self.secondsUntilTimeout)) { + if (self.isTimeoutEnabled) { self.sessionBeingTimed = YES; [self markStartTime]; [self resumeSessionTimer]; @@ -137,14 +154,17 @@ if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) { return; } - - if (!fequal(0, self.secondsUntilWarning) && ![self.sessionWarningTimer isValid]) { - self.sessionWarningTimer = [NSTimer scheduledTimerWithTimeInterval:[self remainingTimeUntilWarning] target:self selector:@selector(sessionTimeoutWarning) userInfo:nil repeats:NO]; - MVMCoreLog(@"Session warning will fire at: %@", self.sessionWarningTimer.fireDate); - } - if (!fequal(0, self.secondsUntilTimeout) && ![self.sessionTimer isValid]) { + + if (self.isTimeoutEnabled && ![self.sessionTimer isValid]) { + // Session timeout, implicitly whileInBackround as no. Note based on scheduledTimerWithTimeInterval, if the remaining time < 0, this will fire near immediately. self.sessionTimer = [NSTimer scheduledTimerWithTimeInterval:[self remainingTimeUntiTimeout] target:self selector:@selector(sessionTimeout:) userInfo:nil repeats:NO]; MVMCoreLog(@"Session timeout will fire at: %@", self.sessionTimer.fireDate); + + // Only setup a warning timer if there is a timout timer. Note based on scheduledTimerWithTimeInterval, if the remaining time < 0, this will fire near immediately. + if (self.isWarningEnabled && ![self.sessionWarningTimer isValid]) { + self.sessionWarningTimer = [NSTimer scheduledTimerWithTimeInterval:[self remainingTimeUntilWarning] target:self selector:@selector(sessionTimeoutWarning) userInfo:nil repeats:NO]; + MVMCoreLog(@"Session warning will fire at: %@", self.sessionWarningTimer.fireDate); + } } }); } @@ -173,6 +193,11 @@ } - (void)appEnteredForeground { + // Special return logic to cancel when returning in warning track. This is not in the revalidateSessionTimestamp in order to prevent API checks to isAppInSession from timing out the session from under the user warning period. + if (self.isWarningEnabled && self.remainingTimeUntilWarning < 0) { + [self sessionTimeout:YES]; + } + // Revalidate first to check if we should be in the timeout state. [self revalidateSessionTimestamp]; [self sendKeepAliveToServer:NO]; @@ -185,9 +210,7 @@ // Checks to make sure session is still valid and that the timer is running. - (void)revalidateSessionTimestamp { if (self.sessionBeingTimed || self.sessionTimedOut) { - NSTimeInterval timeSinceStart = [self timeSinceStart]; - if ((!fequal(0, self.secondsUntilWarning) && timeSinceStart > self.secondsUntilWarning) || (!fequal(0, self.secondsUntilTimeout) && timeSinceStart > self.secondsUntilTimeout)) { - + if (self.isTimeoutEnabled && self.remainingTimeUntiTimeout < 0) { // Timeout if we are passed the warning. [self sessionTimeout:YES]; } else { @@ -197,7 +220,7 @@ } - (BOOL)isAppInSession { - [self revalidateSessionTimestamp]; + [self revalidateSessionTimestamp]; // Possible race condition hazard. Session timeouts will happen as if they are in background. If isAppInSession is called right before foreground trigger, it could potentially suppress the dialog. return self.sessionBeingTimed && !self.sessionTimedOut; } From 1f377dfb515437f8fb1f776f0aa89106dabc77f8 Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Tue, 17 Jan 2023 12:10:43 -0500 Subject: [PATCH 6/6] remainingWarningTime fix. code comment cleanups. --- MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.h | 2 +- MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.h b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.h index cb4db62..04e2eeb 100644 --- a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.h +++ b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.h @@ -30,7 +30,7 @@ #pragma mark - functions to override -/// Can override to provide a time until the warning shows in seconds. Set to 0 if there should be no warning. Default is 0 +/// Can override to provide a time until the warning shows in seconds. Set to 0 if there should be no warning. Default is 0. - (NSTimeInterval)timeUntilWarning; /// Can override to provide a time until the timeout happens in seconds. If there is a warning, then this value is used after the warning happens. Set to 0 if there should be no timeout. Default is 0. diff --git a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m index 191c3a8..6d6e9cd 100644 --- a/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m +++ b/MVMCore/MVMCore/Session/MVMCoreSessionTimeHandler.m @@ -104,7 +104,7 @@ } - (BOOL)isWarningEnabled { - return !fequal(0, self.secondsUntilWarning); + return [self isTimeoutEnabled] && !fequal(0, self.secondsUntilWarning); } - (BOOL)isTimeoutEnabled { @@ -112,7 +112,7 @@ } - (NSTimeInterval)remainingTimeUntilWarning { - if (self.timeTimerStarted < 0 || ![self isTimeoutEnabled]) { + if (self.timeTimerStarted < 0 || ![self isWarningEnabled]) { return 0; } return self.secondsUntilWarning - self.timeSinceStart; @@ -160,7 +160,7 @@ self.sessionTimer = [NSTimer scheduledTimerWithTimeInterval:[self remainingTimeUntiTimeout] target:self selector:@selector(sessionTimeout:) userInfo:nil repeats:NO]; MVMCoreLog(@"Session timeout will fire at: %@", self.sessionTimer.fireDate); - // Only setup a warning timer if there is a timout timer. Note based on scheduledTimerWithTimeInterval, if the remaining time < 0, this will fire near immediately. + // Only setup a warning timer if there is a timeout timer. Note based on scheduledTimerWithTimeInterval, if the remaining time < 0, this will fire near immediately. if (self.isWarningEnabled && ![self.sessionWarningTimer isValid]) { self.sessionWarningTimer = [NSTimer scheduledTimerWithTimeInterval:[self remainingTimeUntilWarning] target:self selector:@selector(sessionTimeoutWarning) userInfo:nil repeats:NO]; MVMCoreLog(@"Session warning will fire at: %@", self.sessionWarningTimer.fireDate); @@ -211,7 +211,7 @@ - (void)revalidateSessionTimestamp { if (self.sessionBeingTimed || self.sessionTimedOut) { if (self.isTimeoutEnabled && self.remainingTimeUntiTimeout < 0) { - // Timeout if we are passed the warning. + // Force a timeout if we are passed the timeout interval. [self sessionTimeout:YES]; } else { [self resumeSessionTimer];