Code review suggestion to use default values. Bug fix for warning track timeouts from the background.

This commit is contained in:
Kyle Matthew Hedden 2023-01-13 18:57:23 -05:00
parent 80512a0b8a
commit 16d169c46c
2 changed files with 38 additions and 16 deletions

View File

@ -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;

View File

@ -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;
}