Added button to expired page (and alert) that lets the user check for a new version

- Added option to disable the option via new `disableUpdateCheckOptionWhenExpired` property
This commit is contained in:
Andreas Linde 2014-01-07 21:47:48 +01:00
parent 5ff12626af
commit 0bd80c91be
3 changed files with 77 additions and 29 deletions

View File

@ -48,6 +48,7 @@
- (NSString *)executableUUID; - (NSString *)executableUUID;
// UI helpers // UI helpers
- (UIWindow *)findVisibleWindow;
- (UINavigationController *)customNavigationControllerWithRootViewController:(UIViewController *)viewController presentationStyle:(UIModalPresentationStyle)presentationStyle; - (UINavigationController *)customNavigationControllerWithRootViewController:(UIViewController *)viewController presentationStyle:(UIModalPresentationStyle)presentationStyle;
- (void)showView:(UIViewController *)viewController; - (void)showView:(UIViewController *)viewController;

View File

@ -200,12 +200,30 @@ typedef NS_ENUM (NSUInteger, BITUpdateSetting) {
When running the app from the App Store, this setting is ignored. When running the app from the App Store, this setting is ignored.
*Default*: nil *Default*: nil
@see disableUpdateCheckOptionWhenExpired
@see [BITUpdateManagerDelegate shouldDisplayExpiryAlertForUpdateManager:] @see [BITUpdateManagerDelegate shouldDisplayExpiryAlertForUpdateManager:]
@see [BITUpdateManagerDelegate didDisplayExpiryAlertForUpdateManager:] @see [BITUpdateManagerDelegate didDisplayExpiryAlertForUpdateManager:]
@warning This only works when using Ad-Hoc provisioning profiles! @warning This only works when using Ad-Hoc provisioning profiles!
*/ */
@property (nonatomic, strong) NSDate *expiryDate; @property (nonatomic, strong) NSDate *expiryDate;
/**
Disable the update check button from expiry screen or alerts
If do not want your users to be able to check for updates once a version is expired,
then enable this property.
If this is not enabled, the users will be able to check for updates and install them
if any is available for the current device.
*Default*: NO
@see expiryDate
@see [BITUpdateManagerDelegate shouldDisplayExpiryAlertForUpdateManager:]
@see [BITUpdateManagerDelegate didDisplayExpiryAlertForUpdateManager:]
@warning This only works when using Ad-Hoc provisioning profiles!
*/
@property (nonatomic) BOOL disableUpdateCheckOptionWhenExpired;
///----------------------------------------------------------------------------- ///-----------------------------------------------------------------------------
/// @name User Interface /// @name User Interface

View File

@ -74,6 +74,9 @@ typedef NS_ENUM(NSInteger, BITUpdateAlertViewTag) {
NSNumber *_versionID; NSNumber *_versionID;
NSString *_versionUUID; NSString *_versionUUID;
NSString *_uuid; NSString *_uuid;
NSString *_blockingScreenMessage;
NSDate *_lastUpdateCheckFromBlockingScreen;
} }
@ -191,7 +194,9 @@ typedef NS_ENUM(NSInteger, BITUpdateAlertViewTag) {
if (shouldShowDefaultAlert) { if (shouldShowDefaultAlert) {
NSString *appName = bit_appName(BITHockeyLocalizedString(@"HockeyAppNamePlaceholder")); NSString *appName = bit_appName(BITHockeyLocalizedString(@"HockeyAppNamePlaceholder"));
[self showBlockingScreen:[NSString stringWithFormat:BITHockeyLocalizedString(@"UpdateExpired"), appName] image:@"authorize_denied.png"]; if (!_blockingScreenMessage)
_blockingScreenMessage = [NSString stringWithFormat:BITHockeyLocalizedString(@"UpdateExpired"), appName];
[self showBlockingScreen:_blockingScreenMessage image:@"authorize_denied.png"];
if (self.delegate != nil && [self.delegate respondsToSelector:@selector(didDisplayExpiryAlertForUpdateManager:)]) { if (self.delegate != nil && [self.delegate respondsToSelector:@selector(didDisplayExpiryAlertForUpdateManager:)]) {
[self.delegate didDisplayExpiryAlertForUpdateManager:self]; [self.delegate didDisplayExpiryAlertForUpdateManager:self];
@ -377,29 +382,6 @@ typedef NS_ENUM(NSInteger, BITUpdateAlertViewTag) {
[[NSUserDefaults standardUserDefaults] synchronize]; [[NSUserDefaults standardUserDefaults] synchronize];
} }
#pragma mark - Window Helper
- (UIWindow *)findVisibleWindow {
UIWindow *visibleWindow = nil;
// if the rootViewController property (available >= iOS 4.0) of the main window is set, we present the modal view controller on top of the rootViewController
NSArray *windows = [[UIApplication sharedApplication] windows];
for (UIWindow *window in windows) {
if (!window.hidden && !visibleWindow) {
visibleWindow = window;
}
if ([UIWindow instancesRespondToSelector:@selector(rootViewController)]) {
if ([window rootViewController]) {
visibleWindow = window;
BITHockeyLog(@"INFO: UIWindow with rootViewController found: %@", visibleWindow);
break;
}
}
}
return visibleWindow;
}
#pragma mark - Init #pragma mark - Init
@ -515,7 +497,7 @@ typedef NS_ENUM(NSInteger, BITUpdateAlertViewTag) {
self.barStyle = UIBarStyleBlack; self.barStyle = UIBarStyleBlack;
BITUpdateViewController *updateViewController = [self hockeyViewController:YES]; BITUpdateViewController *updateViewController = [self hockeyViewController:YES];
if ([self hasNewerMandatoryVersion]) { if ([self hasNewerMandatoryVersion] || [self expiryDateReached]) {
[updateViewController setMandatoryUpdate: YES]; [updateViewController setMandatoryUpdate: YES];
} }
[self showView:updateViewController]; [self showView:updateViewController];
@ -580,9 +562,19 @@ typedef NS_ENUM(NSInteger, BITUpdateAlertViewTag) {
[self.blockingView addSubview:imageView]; [self.blockingView addSubview:imageView];
} }
if (!self.disableUpdateCheckOptionWhenExpired) {
UIButton *checkForUpdateButton = [UIButton buttonWithType:kBITButtonTypeSystem];
checkForUpdateButton.frame = CGRectMake((frame.size.width - 140) / 2.f, frame.size.height - 100, 140, 25);
[checkForUpdateButton setTitle:BITHockeyLocalizedString(@"UpdateButtonCheck") forState:UIControlStateNormal];
[checkForUpdateButton addTarget:self
action:@selector(checkForUpdateForExpiredVersion)
forControlEvents:UIControlEventTouchUpInside];
[self.blockingView addSubview:checkForUpdateButton];
}
if (message != nil) { if (message != nil) {
frame.origin.x = 20; frame.origin.x = 20;
frame.origin.y = frame.size.height - 140; frame.origin.y = frame.size.height - 180;
frame.size.width -= 40; frame.size.width -= 40;
frame.size.height = 70; frame.size.height = 70;
@ -599,6 +591,16 @@ typedef NS_ENUM(NSInteger, BITUpdateAlertViewTag) {
[visibleWindow addSubview:self.blockingView]; [visibleWindow addSubview:self.blockingView];
} }
- (void)checkForUpdateForExpiredVersion {
if (!self.checkInProgress) {
if (!_lastUpdateCheckFromBlockingScreen ||
abs([NSDate timeIntervalSinceReferenceDate] - [_lastUpdateCheckFromBlockingScreen timeIntervalSinceReferenceDate]) > 60) {
_lastUpdateCheckFromBlockingScreen = [NSDate date];
[self checkForUpdateShowFeedback:NO];
}
}
}
// nag the user with neverending alerts if we cannot find out the window for presenting the covering sheet // nag the user with neverending alerts if we cannot find out the window for presenting the covering sheet
- (void)alertFallback:(NSString *)message { - (void)alertFallback:(NSString *)message {
@ -608,6 +610,11 @@ typedef NS_ENUM(NSInteger, BITUpdateAlertViewTag) {
cancelButtonTitle:BITHockeyLocalizedString(@"HockeyOK") cancelButtonTitle:BITHockeyLocalizedString(@"HockeyOK")
otherButtonTitles:nil otherButtonTitles:nil
]; ];
if (!self.disableUpdateCheckOptionWhenExpired && [message isEqualToString:_blockingScreenMessage]) {
[alertView addButtonWithTitle:BITHockeyLocalizedString(@"UpdateButtonCheck")];
}
[alertView setTag:BITUpdateAlertViewTagNeverEndingAlertView]; [alertView setTag:BITUpdateAlertViewTagNeverEndingAlertView];
[alertView show]; [alertView show];
} }
@ -813,7 +820,13 @@ typedef NS_ENUM(NSInteger, BITUpdateAlertViewTag) {
self.receivedData = nil; self.receivedData = nil;
self.urlConnection = nil; self.urlConnection = nil;
self.checkInProgress = NO; self.checkInProgress = NO;
[self reportError:error]; if ([self expiryDateReached]) {
if (!self.blockingView) {
[self alertFallback:_blockingScreenMessage];
}
} else {
[self reportError:error];
}
} }
// api call returned, parsing // api call returned, parsing
@ -910,11 +923,16 @@ typedef NS_ENUM(NSInteger, BITUpdateAlertViewTag) {
} }
_showFeedback = NO; _showFeedback = NO;
} }
} else { } else if (![self expiryDateReached]) {
[self reportError:[NSError errorWithDomain:kBITUpdateErrorDomain [self reportError:[NSError errorWithDomain:kBITUpdateErrorDomain
code:BITUpdateAPIServerReturnedEmptyResponse code:BITUpdateAPIServerReturnedEmptyResponse
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Server returned an empty response.", NSLocalizedDescriptionKey, nil]]]; userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Server returned an empty response.", NSLocalizedDescriptionKey, nil]]];
} }
if (!_updateAlertShowing && [self expiryDateReached] && !self.blockingView) {
[self alertFallback:_blockingScreenMessage];
}
self.receivedData = nil; self.receivedData = nil;
self.urlConnection = nil; self.urlConnection = nil;
} }
@ -1021,17 +1039,28 @@ typedef NS_ENUM(NSInteger, BITUpdateAlertViewTag) {
// invoke the selected action from the action sheet for a location element // invoke the selected action from the action sheet for a location element
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if ([alertView tag] == BITUpdateAlertViewTagNeverEndingAlertView) { if ([alertView tag] == BITUpdateAlertViewTagNeverEndingAlertView) {
[self alertFallback:[alertView message]]; if (buttonIndex == 1) {
[self checkForUpdateForExpiredVersion];
} else {
[self alertFallback:_blockingScreenMessage];
}
return; return;
} }
_updateAlertShowing = NO; _updateAlertShowing = NO;
if (buttonIndex == [alertView firstOtherButtonIndex]) { if (buttonIndex == [alertView firstOtherButtonIndex]) {
// YES button has been clicked // YES button has been clicked
if (self.blockingView) {
[self.blockingView removeFromSuperview];
}
[self showUpdateView]; [self showUpdateView];
} else if (buttonIndex == [alertView firstOtherButtonIndex] + 1) { } else if (buttonIndex == [alertView firstOtherButtonIndex] + 1) {
// YES button has been clicked // YES button has been clicked
(void)[self initiateAppDownload]; (void)[self initiateAppDownload];
} else {
if ([self expiryDateReached] && !self.blockingView) {
[self alertFallback:_blockingScreenMessage];
}
} }
} }