diff --git a/APCAppCore/APCAppCore/Consent/APCConsentBooleanQuestion.m b/APCAppCore/APCAppCore/Consent/APCConsentBooleanQuestion.m index 98111520..65def13d 100644 --- a/APCAppCore/APCAppCore/Consent/APCConsentBooleanQuestion.m +++ b/APCAppCore/APCAppCore/Consent/APCConsentBooleanQuestion.m @@ -48,7 +48,7 @@ - (instancetype)initWithIdentifier:(NSString*)identifier prompt:(NSString*)promp - (BOOL)evaluate:(ORKStepResult*)stepResult { - ORKBooleanQuestionResult* questionResult = stepResult.results.firstObject; + ORKBooleanQuestionResult* _Nullable questionResult = stepResult.results.firstObject; BOOL evaulationResult = false; if ([questionResult isKindOfClass:[ORKBooleanQuestionResult class]]) diff --git a/APCAppCore/APCAppCore/Consent/APCConsentTextChoiceQuestion.m b/APCAppCore/APCAppCore/Consent/APCConsentTextChoiceQuestion.m index 2368c4e7..4f209da1 100644 --- a/APCAppCore/APCAppCore/Consent/APCConsentTextChoiceQuestion.m +++ b/APCAppCore/APCAppCore/Consent/APCConsentTextChoiceQuestion.m @@ -53,18 +53,16 @@ - (instancetype)initWithIdentifier:(NSString*)identifier - (BOOL)evaluate:(ORKStepResult*)stepResult { - ORKChoiceQuestionResult* questionResult = stepResult.results.firstObject; - BOOL evaulationResult = false; + ORKChoiceQuestionResult* _Nullable questionResult = (ORKChoiceQuestionResult*)stepResult.results.firstObject; + BOOL evaulationResult = false; - if ([questionResult isKindOfClass:[ORKChoiceQuestionResult class]]) + if ([questionResult isKindOfClass:[ORKChoiceQuestionResult class]] + && questionResult.choiceAnswers != nil && questionResult.choiceAnswers.count > 0) { - if (questionResult != nil && questionResult.choiceAnswers != nil && questionResult.choiceAnswers.count > 0) - { - NSString* answer = questionResult.choiceAnswers.firstObject; - NSUInteger index = [self.answers indexOfObject:answer]; - - evaulationResult = index == self.indexOfExpectedAnswer; - } + NSString* answer = questionResult.choiceAnswers.firstObject; + NSUInteger index = [self.answers indexOfObject:answer]; + + evaulationResult = (index == self.indexOfExpectedAnswer); } return evaulationResult; diff --git a/APCAppCore/APCAppCore/Library/Categories/NSError+Bridge.m b/APCAppCore/APCAppCore/Library/Categories/NSError+Bridge.m index c7f668aa..83c8a784 100644 --- a/APCAppCore/APCAppCore/Library/Categories/NSError+Bridge.m +++ b/APCAppCore/APCAppCore/Library/Categories/NSError+Bridge.m @@ -106,15 +106,15 @@ - (NSString*)bridgeErrorMessage { message = kAPCServerBusyErrorMessage; } - else if ([code isEqual: @(kSBBInternetNotConnected)]) + else if ([code isEqual: @(SBBErrorCodeInternetNotConnected)]) { message = kAPCNotConnectedErrorMessage; } - else if ([code isEqual:@(kSBBServerNotReachable)]) + else if ([code isEqual:@(SBBErrorCodeServerNotReachable)]) { message = kAPCNotReachableErrorMessage; } - else if ([code isEqual:@(kSBBServerUnderMaintenance)]) + else if ([code isEqual:@(SBBErrorCodeServerUnderMaintenance)]) { message = kAPCServerUnderMaintanenceErrorMessage; } diff --git a/APCAppCore/APCAppCore/Startup/APCAppDelegate.h b/APCAppCore/APCAppCore/Startup/APCAppDelegate.h index 40ba4312..7a333cbd 100644 --- a/APCAppCore/APCAppCore/Startup/APCAppDelegate.h +++ b/APCAppCore/APCAppCore/Startup/APCAppDelegate.h @@ -44,7 +44,7 @@ static NSString* const kDatabaseName = @"db.sqlite"; @class APCDataSubstrate, APCDataMonitor, APCScheduler, APCPasscodeViewController, APCTasksReminderManager, APCPassiveDataCollector, APCFitnessAllocation; -@interface APCAppDelegate : UIResponder +@interface APCAppDelegate : UIResponder @property (nonatomic, strong) APCFitnessAllocation *sevenDayFitnessAllocationData; @property (strong, nonatomic) UITabBarController *tabBarController; @@ -79,6 +79,11 @@ static NSString* const kDatabaseName = @"db.sqlite"; - (NSString*) certificateFileName; +/** + * link for opening the app store. AppDelegate implementations can override. + */ +- (NSURL *)appStoreLinkURL; + //Show Methods - (void) showTabBar; - (void) showOnBoarding; diff --git a/APCAppCore/APCAppCore/Startup/APCAppDelegate.m b/APCAppCore/APCAppCore/Startup/APCAppDelegate.m index 62eeec27..887236aa 100644 --- a/APCAppCore/APCAppCore/Startup/APCAppDelegate.m +++ b/APCAppCore/APCAppCore/Startup/APCAppDelegate.m @@ -41,6 +41,7 @@ #import "APCDemographicUploader.h" #import "APCConstants.h" #import "APCUtilities.h" +#import "APCCatastrophicErrorViewController.h" #import #import @@ -618,24 +619,59 @@ - (BOOL) hadCatastrophicStartupError } - (void) showCatastrophicStartupError +{ + [self showCatastrophicStartupErrorWithMessage:nil buttonTitle:nil action:nil]; +} + +- (void) showCatastrophicStartupErrorWithMessage:(NSString *)message + buttonTitle:(NSString *)buttonTitle + action:(void(^)(void))action { UIStoryboard *storyBoard = [UIStoryboard storyboardWithName: @"CatastrophicError" bundle: [NSBundle appleCoreBundle]]; - UIViewController *errorViewController = [storyBoard instantiateInitialViewController]; + APCCatastrophicErrorViewController *errorViewController = (APCCatastrophicErrorViewController*)[storyBoard instantiateInitialViewController]; + + errorViewController.message = message; + errorViewController.buttonTitle = buttonTitle; + errorViewController.buttonAction = action; self.window.rootViewController = errorViewController; - NSError *error = self.catastrophicStartupError; + + if (message.length == 0) { + + NSError *error = self.catastrophicStartupError; + __block APCAppDelegate *blockSafeSelf = self; + + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ - __block APCAppDelegate *blockSafeSelf = self; + UIAlertController *alert = [UIAlertController simpleAlertWithTitle: error.userInfo [NSLocalizedFailureReasonErrorKey] + message: error.userInfo [NSLocalizedRecoverySuggestionErrorKey]]; - [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + [blockSafeSelf.window.rootViewController presentViewController: alert animated: YES completion: nil]; + }]; + } +} - UIAlertController *alert = [UIAlertController simpleAlertWithTitle: error.userInfo [NSLocalizedFailureReasonErrorKey] - message: error.userInfo [NSLocalizedRecoverySuggestionErrorKey]]; +/*********************************************************************************/ +#pragma mark - Unsupported App Version +/*********************************************************************************/ +- (BOOL)handleUnsupportedAppVersionError:(NSError*)error networkManager:(id __unused)networkManager +{ + NSString *localizedButtonTitle = NSLocalizedStringWithDefaultValue(@"APC_BUTTON_TITLE_GOTO_APP_STORE", @"APCAppCore", APCBundle(), @"Open App Store", @"Button title: Open App Store"); + self.catastrophicStartupError = error; + + [self showCatastrophicStartupErrorWithMessage:[error localizedDescription] + buttonTitle:localizedButtonTitle + action:^{ + [[UIApplication sharedApplication] openURL:[self appStoreLinkURL]]; + }]; + return YES; +} - [blockSafeSelf.window.rootViewController presentViewController: alert animated: YES completion: nil]; - }]; +- (NSURL *)appStoreLinkURL +{ + return [[NSBundle mainBundle] appStoreLinkURL]; } /*********************************************************************************/ diff --git a/APCAppCore/APCAppCore/UI/Errors/APCCatastrophicErrorViewController.h b/APCAppCore/APCAppCore/UI/Errors/APCCatastrophicErrorViewController.h index 3cc9bd2b..28475650 100644 --- a/APCAppCore/APCAppCore/UI/Errors/APCCatastrophicErrorViewController.h +++ b/APCAppCore/APCAppCore/UI/Errors/APCCatastrophicErrorViewController.h @@ -35,4 +35,8 @@ @interface APCCatastrophicErrorViewController : UIViewController +@property (nonatomic) NSString * _Nullable message; +@property (nonatomic) NSString * _Nullable buttonTitle; +@property (nonatomic, copy) void (^ _Nullable buttonAction)(void); + @end diff --git a/APCAppCore/APCAppCore/UI/Errors/APCCatastrophicErrorViewController.m b/APCAppCore/APCAppCore/UI/Errors/APCCatastrophicErrorViewController.m index ec37acb3..54b02097 100644 --- a/APCAppCore/APCAppCore/UI/Errors/APCCatastrophicErrorViewController.m +++ b/APCAppCore/APCAppCore/UI/Errors/APCCatastrophicErrorViewController.m @@ -1,4 +1,4 @@ -// +// // APCCatastrophicErrorViewController.m // APCAppCore // @@ -36,6 +36,8 @@ @interface APCCatastrophicErrorViewController () @property (weak, nonatomic) IBOutlet UILabel *appNameLabel; +@property (weak, nonatomic) IBOutlet UILabel *optionalMessageLabel; +@property (weak, nonatomic) IBOutlet UIButton *optionalActionButton; @end @implementation APCCatastrophicErrorViewController @@ -47,4 +49,30 @@ - (void) viewDidLoad self.appNameLabel.text = [APCUtilities appName]; } +- (void)setMessage:(NSString *)message +{ + _message = message; + dispatch_async(dispatch_get_main_queue(), ^{ + self.optionalMessageLabel.text = message; + self.optionalMessageLabel.hidden = (message.length == 0); + }); +} + +- (void)setButtonTitle:(NSString *)buttonTitle +{ + _buttonTitle = buttonTitle; + dispatch_async(dispatch_get_main_queue(), ^{ + [self.optionalActionButton setTitle:buttonTitle forState:UIControlStateNormal]; + self.optionalActionButton.hidden = (buttonTitle.length == 0); + }); +} + +- (IBAction)buttonTapped:(id __unused)sender +{ + if (self.buttonAction) { + self.buttonAction(); + } +} + + @end diff --git a/APCAppCore/APCAppCore/UI/Errors/CatastrophicError.storyboard b/APCAppCore/APCAppCore/UI/Errors/CatastrophicError.storyboard index 28dedea7..ae9b8df9 100644 --- a/APCAppCore/APCAppCore/UI/Errors/CatastrophicError.storyboard +++ b/APCAppCore/APCAppCore/UI/Errors/CatastrophicError.storyboard @@ -1,8 +1,8 @@ - + - + @@ -22,26 +22,55 @@ -