Require the user to call authenticateInstallation manually

This solves multiple issues:
- Possible crashes at startup because the app is already in the process of presenting another modal view. This way the developer can make sure that only one modal view is being presented
- If the app is showing e.g. a login view on startup, it is now not needed to turn off automatic mode and setup the complete auth workflow manually and simply invoke `authenticateInstallation` after the login view is either fully presented (`viewDidLoad` finished) or the user did log in
This commit is contained in:
Andreas Linde
2013-10-10 02:39:44 +02:00
parent 2788b749d8
commit 7052f0cd7a
3 changed files with 78 additions and 11 deletions

View File

@@ -111,6 +111,13 @@ typedef NS_ENUM(NSUInteger, BITAuthenticatorAppRestrictionEnforcementFrequency)
* sure only users who are testers of your app are allowed to run it.
*
* This module automatically disables itself when running in an App Store build by default!
*
* @warning It is mandatory to call `authenticateInstallation` somewhen after calling
* `[[BITHockeyManager sharedHockeyManager] startManager]` or disable `automaticMode`
* and fully customize the identification and validation workflow yourself.
* If your app shows a modal view on startup, make sure to call `authenticateInstallation`
* either once your modal view is fully presented (e.g. its `viewDidLoad:` method is processed)
* or once your modal view is dismissed.
*/
@interface BITAuthenticator : BITHockeyBaseManager
@@ -285,6 +292,27 @@ typedef NS_ENUM(NSUInteger, BITAuthenticatorAppRestrictionEnforcementFrequency)
/// @name Authentication
///-----------------------------------------------------------------------------
/**
* Invoked automatic identification and validation
*
* If the `BITAuthenticator` is in automatic mode this will initiate identifying
* the current user according to the type specified in `identificationType` and
* validate if the identified user is allowed to run this application.
*
* If the user is not yet identified it will present a modal view asking the user to
* provide the required information.
*
* If your app provides it's own startup modal screen, e.g. a guide or a login, then
* you might either call this method once that UI is fully presented or once
* the user e.g. did actually login already.
*
* @warning You need to call this method in your code even if automatic mode is enabled!
*
* @see identificationType
* @see automaticMode
*/
- (void) authenticateInstallation;
/**
* Identifies the user according to the type specified in `identificationType`.
*

View File

@@ -50,6 +50,8 @@ static NSString* const kBITAuthenticatorAuthTokenTypeKey = @"BITAuthenticatorAut
id _appDidBecomeActiveObserver;
id _appWillResignActiveObserver;
UIViewController *_authenticationController;
BOOL _isSetup;
}
- (void)dealloc {
@@ -63,6 +65,7 @@ static NSString* const kBITAuthenticatorAuthTokenTypeKey = @"BITAuthenticatorAut
_identificationType = BITAuthenticatorIdentificationTypeAnonymous;
_automaticMode = YES;
_isSetup = NO;
_restrictApplicationUsage = NO;
_restrictionEnforcementFrequency = BITAuthenticatorAppRestrictionEnforcementOnFirstLaunch;
}
@@ -74,20 +77,36 @@ static NSString* const kBITAuthenticatorAuthTokenTypeKey = @"BITAuthenticatorAut
//disabled in the appStore
if([self isAppStoreEnvironment]) return;
switch ([[UIApplication sharedApplication] applicationState]) {
case UIApplicationStateActive:
[self authenticate];
break;
case UIApplicationStateBackground:
case UIApplicationStateInactive:
// do nothing, wait for active state
break;
}
[self registerObservers];
_isSetup = YES;
}
#pragma mark -
- (void)authenticateInstallation {
//disabled in the appStore
if([self isAppStoreEnvironment]) return;
// make sure this is called after startManager so all modules are fully setup
if (!_isSetup) {
[self performSelector:@selector(authenticateInstallation) withObject:nil afterDelay:0.1];
}
static dispatch_once_t authenticatePredicate;
dispatch_once(&authenticatePredicate, ^{
switch ([[UIApplication sharedApplication] applicationState]) {
case UIApplicationStateActive:
[self authenticate];
break;
case UIApplicationStateBackground:
case UIApplicationStateInactive:
// do nothing, wait for active state
break;
}
[self registerObservers];
});
}
- (void) authenticate {
//when running in manual mode, we don't actually do anything ourselves
if(!self.automaticMode) return;

View File

@@ -26,6 +26,22 @@ Previous versions of HockeySDK for iOS used the response of the method `UIDevice
The user needs to enter the email address and password of his HockeyApp account.
The `BITAuthenticator` class doesn't do anything on its own. In addition to setting up the behavior, you also need to trigger the process yourself.
If `automaticMode` is enabled (default), you simply need to place a call to `[[BITHockeyManager sharedHockeyManager] authenticateInstallation]` in your code. This will show a UI asking for identification details according to the chosen strategy.
**IMPORTANT**: If your app shows a modal view on startup, make sure to call `authenticateInstallation` either once your modal view is fully presented (e.g. its `viewDidLoad:` method is processed) or once your modal view is dismissed.
If `automaticMode` is disabled, you need to implement your own workflow by using
- (void) identifyWithCompletion:(void(^)(BOOL identified, NSError *error)) completion;
to identify the current user depending on your strategy and
- (void) validateWithCompletion:(void(^)(BOOL validated, NSError *error)) completion;
to validate the user may still use the app if required.
The following sections explain the different strategies and their advantages / disadvantages.
<a name="no-authentication"></a>
@@ -35,6 +51,7 @@ Initialize HockeySDK with the following code:
[[BITHockeyManager sharedHockeyManager] configureWithIdentifier:@"<#APP_ID#>" delegate:self];
[[BITHockeyManager sharedHockeyManager] startManager];
[[BITHockeyManager sharedHockeyManager] authenticateInstallation];
Replace APP_ID with the your App ID (can be found on the app page).
@@ -57,6 +74,7 @@ Initialize HockeySDK with the following code:
[[BITHockeyManager sharedHockeyManager] configureWithIdentifier:@"<#APP_ID#>" delegate:self];
[[BITHockeyManager sharedHockeyManager].authenticator setIdentificationType:BITAuthenticatorIdentificationTypeDevice];
[[BITHockeyManager sharedHockeyManager] startManager];
[[BITHockeyManager sharedHockeyManager] authenticateInstallation];
Replace APP_ID with the your App ID (can be found on the app page).
@@ -104,6 +122,7 @@ Initialize HockeySDK with the following code:
[[BITHockeyManager sharedHockeyManager].authenticator setAuthenticationSecret:@"<#SECRET#>"];
[[BITHockeyManager sharedHockeyManager].authenticator setIdentificationType:BITAuthenticatorIdentificationTypeHockeyAppEmail];
[[BITHockeyManager sharedHockeyManager] startManager];
[[BITHockeyManager sharedHockeyManager] authenticateInstallation];
Replace APP_ID with the your App ID and SECRET with the Secret (both values can be found on the app page).
@@ -127,6 +146,7 @@ Initialize HockeySDK with the following code:
[[BITHockeyManager sharedHockeyManager] configureWithIdentifier:@"APP_ID" delegate:self];
[[BITHockeyManager sharedHockeyManager].authenticator setIdentificationType:BITAuthenticatorIdentificationTypeHockeyAppUser];
[[BITHockeyManager sharedHockeyManager] startManager];
[[BITHockeyManager sharedHockeyManager] authenticateInstallation];
Replace APP_ID with the your App ID (can be found on the app page).