FRAMechanismReaderAction.m revision 6a2ae9c7fb4d2c40d75cab0edaf940f22c18224f
3112N/A/*
3112N/A * The contents of this file are subject to the terms of the Common Development and
3112N/A * Distribution License (the License). You may not use this file except in compliance with the
3112N/A * License.
3112N/A *
3112N/A * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
3112N/A * specific language governing permission and limitations under the License.
3112N/A *
3112N/A * When distributing Covered Software, include this CDDL Header Notice in each file and include
3112N/A * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
3112N/A * Header, with the fields enclosed by brackets [] replaced by your own identifying
3112N/A * information: "Portions copyright [year] [name of copyright owner]".
3112N/A *
3112N/A * Copyright 2016 ForgeRock AS.
3112N/A */
3112N/A
3112N/A#import "FRAActivityIndicator.h"
3112N/A#import "FRABlockAlertView.h"
3112N/A#import "FRAError.h"
3112N/A#import "FRAIdentity.h"
3112N/A#import "FRAUriMechanismReader.h"
3112N/A#import "FRAMechanismReaderAction.h"
3112N/A
4251N/A@implementation FRAMechanismReaderAction {
3112N/A FRAActivityIndicator *activityIndicator;
4458N/A}
4458N/A
4458N/A#pragma mark -
4458N/A#pragma mark Lifecyle
3832N/A
3832N/A- (instancetype)initWithMechanismReader:(FRAUriMechanismReader *)mechanismReader {
4458N/A self = [super init];
3832N/A if (self) {
3832N/A _mechanismReader = mechanismReader;
4458N/A }
3832N/A return self;
4714N/A}
4458N/A
4714N/A#pragma mark -
4251N/A#pragma mark Public Methods
4714N/A
4714N/A- (BOOL)read:(NSString *)code view:(UIView *)view {
4251N/A [self showActivityIndicator:view];
4616N/A
3832N/A NSError *error;
4458N/A FRAMechanism *mechanism = [_mechanismReader parseFromString:code handler:[self mechanismReadCallback] error:&error];
4458N/A
4458N/A if (mechanism) {
4458N/A return YES;
4458N/A }
4458N/A
4458N/A if (error && error.code == FRADuplicateMechanism) {
4495N/A [self handleDuplicateMechanism:code error:&error];
4495N/A return YES;
4495N/A }
4495N/A
4495N/A [self hideActivityIndicator];
4495N/A [self showAlert:error];
4458N/A
4458N/A return NO;
4458N/A}
4458N/A
4458N/A#pragma mark -
4714N/A#pragma mark Private Methods
4714N/A
4714N/A/*!
4458N/A * Displays the activity indicator and disables the current view.
4458N/A *
4458N/A * @param view The current view.
4495N/A */
4458N/A- (void)showActivityIndicator:(UIView *)view {
4458N/A if (!view) {
4458N/A return;
4458N/A }
4458N/A
4458N/A view.userInteractionEnabled = NO;
4723N/A activityIndicator = [[FRAActivityIndicator alloc] init:NSLocalizedString(@"qr_code_scan_contact_server", nil)];
4458N/A [view addSubview:activityIndicator];
4458N/A}
4458N/A
4458N/A/*!
4458N/A * Hides the activity indicator and enables the current view.
4458N/A */
4458N/A- (void)hideActivityIndicator {
880N/A activityIndicator.superview.userInteractionEnabled = YES;
4714N/A [activityIndicator removeFromSuperview];
4714N/A}
4714N/A
4714N/A/*!
3832N/A * Handles duplicate mechanism detection.
4458N/A *
4723N/A * @param code The code with the mechanism details.
4458N/A * @param error If an error occurs, upon returns contains an NSError object that describes the problem. If you are not interested in possible errors, you may pass in NULL.
4458N/A */
4458N/A- (void)handleDuplicateMechanism:(NSString *)code error:(NSError *__autoreleasing*)error {
4458N/A FRAIdentity *identity = [(*error).userInfo valueForKey:@"identity"];
4458N/A FRAMechanism *duplicateMechanism = [(*error).userInfo valueForKey:@"mechanism"];
900N/A FRABlockAlertView *alertView = [[FRABlockAlertView alloc] initWithTitle:NSLocalizedString(@"warning", nil)
4458N/A message:(*error).localizedDescription
900N/A delegate:nil
927N/A cancelButtonTitle:NSLocalizedString(@"cancel", nil)
900N/A otherButtonTitle:NSLocalizedString(@"ok", nil)
4714N/A handler:[self duplicateMechanismCallback:code identity:identity mechanism:duplicateMechanism error:error]];
3832N/A [alertView show];
4495N/A}
4714N/A
4458N/A/*!
4714N/A * Generates a duplicate mechanism callback which once confirmed will remove the duplicate mechanism and re-parse the URL to add in the mechanism.
4495N/A *
4458N/A * @param code The code with the mechanism details.
4716N/A * @param identity The identity the mechanism is added to.
4716N/A * @param mechanism The duplicate mechanism.
4495N/A * @param error If an error occurs, upon returns contains an NSError object that describes the problem. If you are not interested in possible errors, you may pass in NULL.
4459N/A * @return The callback block.
4459N/A */
4631N/A- (void(^)(NSInteger))duplicateMechanismCallback:(NSString *)code identity:(FRAIdentity *)identity mechanism:(FRAMechanism *)mechanism error:(NSError *__autoreleasing*) error {
return ^(NSInteger selection) {
const NSInteger okButton = 0;
if (selection == okButton) {
BOOL successfullyRemoved =[identity removeMechanism:mechanism error:error];
if (successfullyRemoved) {
[_mechanismReader parseFromString:code handler:[self mechanismReadCallback] error:error];
}
} else {
[self hideActivityIndicator];
}
};
}
/*!
* Generates a callback for any asynchronous operation happening when reading a QR code.
*
* @return The callback block.
*/
- (void(^)(BOOL, NSError *))mechanismReadCallback {
return ^(BOOL success, NSError *error) {
[self hideActivityIndicator];
if (!success) {
[self showAlert:error];
}
};
}
/*!
* Displays an alert message to the user.
*
* @param error The error to display to the user.
*
*/
- (void)showAlert:(NSError *)error {
FRABlockAlertView *alertView = [[FRABlockAlertView alloc] initWithTitle:NSLocalizedString(@"qr_code_scan_error_title", nil)
message:[self errorMessage:error]
delegate:nil
cancelButtonTitle:NSLocalizedString(@"ok", nil)
otherButtonTitle:nil
handler:nil];
[alertView show];
}
/*!
* Gets the localized error message to display to the user.
*
* @param error The error to display to the user.
*
*/
- (NSString *)errorMessage:(NSError *)error {
if (!error) {
return nil;
}
switch (error.code) {
case FRANetworkFailure:
return NSLocalizedString(@"qr_code_scan_error_network_failure_message", nil);
case FRAMissingDeviceId:
return NSLocalizedString(@"qr_code_scan_error_no_device_id_message", nil);
case FRAInvalidQRCode:
return NSLocalizedString(@"qr_code_scan_error_invalid_code", nil);
default:
return nil;
}
}
@end