Bladeren bron

PAPasscode: use the pod instead of individual files and added error handling

Carola Nitz 7 jaren geleden
bovenliggende
commit
7ca4866fa3

+ 0 - 75
PAPasscode/PAPasscodeViewController.h

@@ -1,75 +0,0 @@
-//Copyright (c) 2012, Denis Hennessy (Peer Assembly - http://peerassembly.com)
-//All rights reserved.
-//                                    
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions are met:
-//  * Redistributions of source code must retain the above copyright
-//  notice, this list of conditions and the following disclaimer.
-//  * Redistributions in binary form must reproduce the above copyright
-//  notice, this list of conditions and the following disclaimer in the
-//  documentation and/or other materials provided with the distribution.
-//  * Neither the name of Peer Assembly, Denis Hennessy nor the
-//  names of its contributors may be used to endorse or promote products
-//  derived from this software without specific prior written permission.
-//                                    
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-//DISCLAIMED. IN NO EVENT SHALL PEER ASSEMBLY OR DENIS HENNESSY BE LIABLE FOR ANY
-//DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-//ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-//(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#import <UIKit/UIKit.h>
-
-typedef enum {
-    PasscodeActionSet,
-    PasscodeActionEnter,
-    PasscodeActionChange
-} PasscodeAction;
-
-@class PAPasscodeViewController;
-
-@protocol PAPasscodeViewControllerDelegate <NSObject>
-
-@optional
-
-- (void)PAPasscodeViewControllerDidCancel:(PAPasscodeViewController *)controller;
-- (void)PAPasscodeViewControllerDidChangePasscode:(PAPasscodeViewController *)controller;
-- (void)PAPasscodeViewControllerDidEnterAlternativePasscode:(PAPasscodeViewController *)controller;
-- (void)PAPasscodeViewControllerDidEnterPasscode:(PAPasscodeViewController *)controller;
-- (void)PAPasscodeViewControllerDidSetPasscode:(PAPasscodeViewController *)controller;
-- (void)PAPasscodeViewController:(PAPasscodeViewController *)controller didFailToEnterPasscode:(NSInteger)attempts;
-
-@end
-
-@interface PAPasscodeViewController : UIViewController {
-    UIView *contentView;
-    NSInteger phase;
-    UILabel *promptLabel;
-    UILabel *messageLabel;
-    UIImageView *failedImageView;
-    UILabel *failedAttemptsLabel;
-    UITextField *passcodeTextField;
-    UIImageView *digitImageViews[4];
-    UIImageView *snapshotImageView;
-}
-
-@property (strong) UIView *backgroundView;
-@property (readonly) PasscodeAction action;
-@property (weak) id<PAPasscodeViewControllerDelegate> delegate;
-@property (strong) NSString *alternativePasscode;
-@property (strong) NSString *passcode;
-@property (assign) BOOL simple;
-@property (assign) NSInteger failedAttempts;
-@property (strong) NSString *enterPrompt;
-@property (strong) NSString *confirmPrompt;
-@property (strong) NSString *changePrompt;
-@property (strong) NSString *message;
-
-- (id)initForAction:(PasscodeAction)action;
-
-@end

+ 0 - 416
PAPasscode/PAPasscodeViewController.m

@@ -1,416 +0,0 @@
-//Copyright (c) 2012, Denis Hennessy (Peer Assembly - http://peerassembly.com)
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions are met:
-//  * Redistributions of source code must retain the above copyright
-//  notice, this list of conditions and the following disclaimer.
-//  * Redistributions in binary form must reproduce the above copyright
-//  notice, this list of conditions and the following disclaimer in the
-//  documentation and/or other materials provided with the distribution.
-//  * Neither the name of Peer Assembly, Denis Hennessy nor the
-//  names of its contributors may be used to endorse or promote products
-//  derived from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-//DISCLAIMED. IN NO EVENT SHALL PEER ASSEMBLY OR DENIS HENNESSY BE LIABLE FOR ANY
-//DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-//ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-//(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#import <QuartzCore/QuartzCore.h>
-#import "PAPasscodeViewController.h"
-
-#define NAVBAR_HEIGHT   66
-#define PROMPT_HEIGHT   90
-#define DIGIT_SPACING   25
-#define DIGIT_WIDTH     19
-#define DIGIT_HEIGHT    1
-#define MARKER_WIDTH    16
-#define MARKER_HEIGHT   1
-#define MARKER_X        1.5
-#define MARKER_Y        -18
-#define MESSAGE_HEIGHT  90
-#define FAILED_LCAP     19
-#define FAILED_RCAP     19
-#define FAILED_HEIGHT   26
-#define FAILED_MARGIN   10
-#define TEXTFIELD_MARGIN 8
-#define SLIDE_DURATION  0.3
-
-@interface PAPasscodeViewController ()
-- (void)cancel:(id)sender;
-- (void)handleFailedAttempt;
-- (void)handleCompleteField;
-- (void)passcodeChanged:(id)sender;
-- (void)resetFailedAttempts;
-- (void)showFailedAttempts;
-- (void)showScreenForPhase:(NSInteger)phase animated:(BOOL)animated;
-@end
-
-@implementation PAPasscodeViewController
-
-- (id)initForAction:(PasscodeAction)action {
-    self = [super init];
-    if (self) {
-        _action = action;
-        switch (action) {
-            case PasscodeActionSet:
-                self.title = NSLocalizedString(@"PASSCODE_SET", nil);
-                _enterPrompt = NSLocalizedString(@"ENTER_PASSCODE", nil);
-                _confirmPrompt = NSLocalizedString(@"REENTER_PASSCODE", nil);
-                break;
-                
-            case PasscodeActionEnter:
-                self.title = NSLocalizedString(@"ENTER_PASSCODE", nil);
-                _enterPrompt = NSLocalizedString(@"ENTER_PASSCODE", nil);
-                break;
-                
-            case PasscodeActionChange:
-                self.title = NSLocalizedString(@"PASSCODE_CHANGE", nil);
-                _changePrompt = NSLocalizedString(@"PASSCODE_ENTER_OLD", nil);
-                _enterPrompt = NSLocalizedString(@"PASSCODE_ENTER_NEW", nil);
-                _confirmPrompt = NSLocalizedString(@"PASSCODE_REENTER_NEW", nil);
-                break;
-        }
-        self.modalPresentationStyle = UIModalPresentationFormSheet;
-        _simple = YES;
-    }
-    return self;
-}
-
-- (void)loadView {
-    UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
-    view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
-
-    self.navigationController.navigationBarHidden = YES;
-
-    UINavigationBar *navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, view.bounds.size.width, NAVBAR_HEIGHT)];
-    navigationBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
-    navigationBar.items = @[self.navigationItem];
-    navigationBar.barTintColor = [UIColor VLCOrangeTintColor];
-    navigationBar.tintColor = [UIColor whiteColor];
-    navigationBar.titleTextAttributes = @{ NSForegroundColorAttributeName : [UIColor whiteColor] };
-    [view addSubview:navigationBar];
-    
-    contentView = [[UIView alloc] initWithFrame:CGRectMake(0, NAVBAR_HEIGHT, view.bounds.size.width, view.bounds.size.height-NAVBAR_HEIGHT)];
-    contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
-    if (_backgroundView) {
-        [contentView addSubview:_backgroundView];
-    }
-    contentView.backgroundColor = [UIColor VLCDarkBackgroundColor];
-    [view addSubview:contentView];
-
-    CGFloat panelWidth = DIGIT_WIDTH*4+DIGIT_SPACING*3;
-    if (_simple) {
-        UIView *digitPanel = [[UIView alloc] initWithFrame:CGRectMake(0, 0, panelWidth, DIGIT_HEIGHT)];
-        digitPanel.frame = CGRectOffset(digitPanel.frame, (contentView.bounds.size.width - panelWidth) / 2., PROMPT_HEIGHT);
-        digitPanel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
-        [contentView addSubview:digitPanel];
-        
-        UIImage *backgroundImage = [UIImage imageNamed:@"papasscode_background"];
-        UIImage *markerImage = [UIImage imageNamed:@"papasscode_marker"];
-
-        CGFloat xLeft = 0;
-        for (int i=0;i<4;i++) {
-            UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:backgroundImage];
-            backgroundImageView.frame = CGRectOffset(backgroundImageView.frame, xLeft, 0);
-            [digitPanel addSubview:backgroundImageView];
-            digitImageViews[i] = [[UIImageView alloc] initWithImage:markerImage];
-            digitImageViews[i].autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
-            digitImageViews[i].frame = CGRectOffset(digitImageViews[i].frame, backgroundImageView.frame.origin.x+MARKER_X, MARKER_Y);
-
-            [digitPanel addSubview:digitImageViews[i]];
-            xLeft += DIGIT_SPACING + backgroundImage.size.width;
-        }
-        passcodeTextField = [[UITextField alloc] initWithFrame:digitPanel.frame];
-        passcodeTextField.hidden = YES;
-    } else {
-        UIView *passcodePanel = [[UIView alloc] initWithFrame:CGRectMake(0, 0, panelWidth, DIGIT_HEIGHT)];
-        passcodePanel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
-        passcodePanel.frame = CGRectOffset(passcodePanel.frame, (contentView.bounds.size.width-passcodePanel.bounds.size.width)/2, PROMPT_HEIGHT);
-        passcodePanel.frame = CGRectInset(passcodePanel.frame, TEXTFIELD_MARGIN, TEXTFIELD_MARGIN);
-        passcodePanel.layer.borderColor = [UIColor colorWithRed:0.65 green:0.67 blue:0.70 alpha:1.0].CGColor;
-        passcodePanel.layer.borderWidth = 1.0;
-        passcodePanel.layer.cornerRadius = 5.0;
-        passcodePanel.layer.shadowColor = [UIColor whiteColor].CGColor;
-        passcodePanel.layer.shadowOffset = CGSizeMake(0, 1);
-        passcodePanel.layer.shadowOpacity = 1.0;
-        passcodePanel.layer.shadowRadius = 1.0;
-        passcodePanel.backgroundColor = [UIColor whiteColor];
-        [contentView addSubview:passcodePanel];
-        passcodeTextField = [[UITextField alloc] initWithFrame:CGRectInset(passcodePanel.frame, 6, 6)];
-    }
-    passcodeTextField.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
-    passcodeTextField.borderStyle = UITextBorderStyleNone;
-    passcodeTextField.secureTextEntry = YES;
-    passcodeTextField.textColor = [UIColor colorWithRed:0.23 green:0.33 blue:0.52 alpha:1.0];
-    passcodeTextField.keyboardType = UIKeyboardTypeNumberPad;
-    [passcodeTextField addTarget:self action:@selector(passcodeChanged:) forControlEvents:UIControlEventEditingChanged];
-    [contentView addSubview:passcodeTextField];
-
-    promptLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, contentView.bounds.size.width, PROMPT_HEIGHT)];
-    promptLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
-    promptLabel.backgroundColor = [UIColor clearColor];
-    promptLabel.textColor = [UIColor VLCLightTextColor];
-    promptLabel.font = [UIFont boldSystemFontOfSize:17];
-    promptLabel.shadowColor = [UIColor VLCDarkTextShadowColor];
-    promptLabel.shadowOffset = CGSizeMake(0, 1);
-    promptLabel.textAlignment = NSTextAlignmentCenter;
-    promptLabel.numberOfLines = 0;
-    [contentView addSubview:promptLabel];
-    
-    messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, PROMPT_HEIGHT+DIGIT_HEIGHT, contentView.bounds.size.width, MESSAGE_HEIGHT)];
-    messageLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
-    messageLabel.backgroundColor = [UIColor clearColor];
-    messageLabel.textColor = [UIColor VLCLightTextColor];
-    messageLabel.font = [UIFont boldSystemFontOfSize:14];
-    messageLabel.shadowColor = [UIColor VLCDarkTextShadowColor];
-    messageLabel.shadowOffset = CGSizeMake(0, 1);
-    messageLabel.textAlignment = NSTextAlignmentCenter;
-    messageLabel.numberOfLines = 0;
-	messageLabel.text = _message;
-    [contentView addSubview:messageLabel];
-        
-    UIImage *failedBg = [[UIImage imageNamed:@"papasscode_failed_bg"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, FAILED_LCAP, 0, FAILED_RCAP)];
-    failedImageView = [[UIImageView alloc] initWithImage:failedBg];
-    failedImageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
-    failedImageView.hidden = YES;
-    [contentView addSubview:failedImageView];
-    
-    failedAttemptsLabel = [[UILabel alloc] initWithFrame:CGRectZero];
-    failedAttemptsLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
-    failedAttemptsLabel.backgroundColor = [UIColor clearColor];
-    failedAttemptsLabel.textColor = [UIColor whiteColor];
-    failedAttemptsLabel.font = [UIFont boldSystemFontOfSize:15];
-    failedAttemptsLabel.shadowColor = [UIColor blackColor];
-    failedAttemptsLabel.shadowOffset = CGSizeMake(0, -1);
-    failedAttemptsLabel.textAlignment = NSTextAlignmentCenter;
-    failedAttemptsLabel.hidden = YES;
-    [contentView addSubview:failedAttemptsLabel];
-    
-    self.view = view;
-}
-
-- (void)viewDidLoad {
-    [super viewDidLoad];
-    
-    if ([_delegate respondsToSelector:@selector(PAPasscodeViewControllerDidCancel:)]) {
-        if (_simple) {
-            self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel:)];
-        } else {
-            self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel:)];
-        }
-    }
-    
-    if (_failedAttempts > 0) {
-        [self showFailedAttempts];
-    }
-}
-
-- (void)viewWillAppear:(BOOL)animated {
-    [super viewWillAppear:animated];
-    [self showScreenForPhase:0 animated:NO];
-    [passcodeTextField becomeFirstResponder];
-}
-
-- (void)viewWillDisappear:(BOOL)animated {
-    [super viewWillDisappear:animated];
-    [passcodeTextField resignFirstResponder];
-}
-
-- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
-    return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown;
-}
-
-- (void)cancel:(id)sender {
-    [_delegate PAPasscodeViewControllerDidCancel:self];
-}
-
-#pragma mark - implementation helpers
-
-- (void)handleCompleteField {
-    NSString *text = passcodeTextField.text;
-    switch (_action) {
-        case PasscodeActionSet:
-            if (phase == 0) {
-                _passcode = text;
-                messageLabel.text = @"";
-                [self showScreenForPhase:1 animated:YES];
-            } else {
-                if ([text isEqualToString:_passcode]) {
-                    if ([_delegate respondsToSelector:@selector(PAPasscodeViewControllerDidSetPasscode:)]) {
-                        [_delegate PAPasscodeViewControllerDidSetPasscode:self];
-                    }
-                } else {
-                    [self showScreenForPhase:0 animated:YES];
-                    messageLabel.text = NSLocalizedString(@"PASSCODES_DID_NOT_MATCH", nil);
-                }
-            }
-            break;
-            
-        case PasscodeActionEnter:
-            if ([text isEqualToString:_passcode]) {
-                [self resetFailedAttempts];
-                if ([_delegate respondsToSelector:@selector(PAPasscodeViewControllerDidEnterPasscode:)]) {
-                    [_delegate PAPasscodeViewControllerDidEnterPasscode:self];
-                }
-            } else {
-                if (_alternativePasscode && [text isEqualToString:_alternativePasscode]) {
-                    [self resetFailedAttempts];
-                    if ([_delegate respondsToSelector:@selector(PAPasscodeViewControllerDidEnterAlternativePasscode:)]) {
-                        [_delegate PAPasscodeViewControllerDidEnterAlternativePasscode:self];
-                    }
-                } else {
-                    [self handleFailedAttempt];
-                    [self showScreenForPhase:0 animated:NO];
-                }
-            }
-            break;
-            
-        case PasscodeActionChange:
-            if (phase == 0) {
-                if ([text isEqualToString:_passcode]) {
-                    [self resetFailedAttempts];
-                    [self showScreenForPhase:1 animated:YES];
-                } else {
-                    [self handleFailedAttempt];
-                    [self showScreenForPhase:0 animated:NO];
-                }
-            } else if (phase == 1) {
-                _passcode = text;
-                messageLabel.text = @"";
-                [self showScreenForPhase:2 animated:YES];
-            } else {
-                if ([text isEqualToString:_passcode]) {
-                    if ([_delegate respondsToSelector:@selector(PAPasscodeViewControllerDidChangePasscode:)]) {
-                        [_delegate PAPasscodeViewControllerDidChangePasscode:self];
-                    }
-                } else {
-                    [self showScreenForPhase:1 animated:YES];
-                    messageLabel.text = NSLocalizedString(@"PASSCODES_DID_NOT_MATCH", nil);
-                }
-            }
-            break;
-    }
-}
-
-- (void)handleFailedAttempt {
-    _failedAttempts++;
-    [self showFailedAttempts];
-    if ([_delegate respondsToSelector:@selector(PAPasscodeViewController:didFailToEnterPasscode:)]) {
-        [_delegate PAPasscodeViewController:self didFailToEnterPasscode:_failedAttempts];
-    }
-}
-
-- (void)resetFailedAttempts {
-    messageLabel.hidden = NO;
-    failedImageView.hidden = YES;
-    failedAttemptsLabel.hidden = YES;
-    _failedAttempts = 0;
-}
-
-- (void)showFailedAttempts {
-    messageLabel.hidden = YES;
-    failedImageView.hidden = NO;
-    failedAttemptsLabel.hidden = NO;
-    if (_failedAttempts == 1) {
-        failedAttemptsLabel.text = NSLocalizedString(@"PASSCODE_FAILED_1", nil);
-    } else {
-        failedAttemptsLabel.text = [NSString stringWithFormat:NSLocalizedString(@"PASSCODE_FAILED_FORMAT", nil), _failedAttempts];
-    }
-    [failedAttemptsLabel sizeToFit];
-    CGFloat bgWidth = failedAttemptsLabel.bounds.size.width + FAILED_MARGIN*2;
-    CGFloat x = floor((contentView.bounds.size.width-bgWidth)/2);
-    CGFloat y = PROMPT_HEIGHT+DIGIT_HEIGHT+floor((MESSAGE_HEIGHT-FAILED_HEIGHT)/2);
-    failedImageView.frame = CGRectMake(x, y, bgWidth, FAILED_HEIGHT);
-    x = failedImageView.frame.origin.x+FAILED_MARGIN;
-    y = failedImageView.frame.origin.y+floor((failedImageView.bounds.size.height-failedAttemptsLabel.frame.size.height)/2);
-    failedAttemptsLabel.frame = CGRectMake(x, y, failedAttemptsLabel.bounds.size.width, failedAttemptsLabel.bounds.size.height);
-}
-
-- (void)passcodeChanged:(id)sender {
-    NSString *text = passcodeTextField.text;
-    if (_simple) {
-        if ([text length] > 4) {
-            text = [text substringToIndex:4];
-        }
-        for (int i=0;i<4;i++) {
-            digitImageViews[i].hidden = i >= [text length];
-        }
-        if ([text length] == 4) {
-            [self handleCompleteField];
-        }
-    } else {
-        self.navigationItem.rightBarButtonItem.enabled = [text length] > 0;
-    }
-}
-
-- (void)showScreenForPhase:(NSInteger)newPhase animated:(BOOL)animated {
-    CGFloat dir = (newPhase > phase) ? 1 : -1;
-    if (animated) {
-        UIGraphicsBeginImageContext(self.view.bounds.size);
-        [contentView.layer renderInContext:UIGraphicsGetCurrentContext()];
-        UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
-        UIGraphicsEndImageContext();
-        snapshotImageView = [[UIImageView alloc] initWithImage:snapshot];
-        snapshotImageView.frame = CGRectOffset(snapshotImageView.frame, -contentView.frame.size.width*dir, 0);
-        [contentView addSubview:snapshotImageView];
-    }
-    phase = newPhase;
-    passcodeTextField.text = @"";
-    if (!_simple) {
-        BOOL finalScreen = _action == PasscodeActionSet && phase == 1;
-        finalScreen |= _action == PasscodeActionEnter && phase == 0;
-        finalScreen |= _action == PasscodeActionChange && phase == 2;
-        if (finalScreen) {
-            self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(handleCompleteField)];
-        } else {
-            self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"BUTTON_NEXT", nil) style:UIBarButtonItemStylePlain target:self action:@selector(handleCompleteField)];
-        }
-        self.navigationItem.rightBarButtonItem.enabled = NO;
-    }
-    
-    switch (_action) {
-        case PasscodeActionSet:
-            if (phase == 0) {
-                promptLabel.text = _enterPrompt;
-            } else {
-                promptLabel.text = _confirmPrompt;
-            }
-            break;
-            
-        case PasscodeActionEnter:
-            promptLabel.text = _enterPrompt;
-            break;
-            
-        case PasscodeActionChange:
-            if (phase == 0) {
-                promptLabel.text = _changePrompt;
-            } else if (phase == 1) {
-                promptLabel.text = _enterPrompt;
-            } else {
-                promptLabel.text = _confirmPrompt;
-            }
-            break;
-    }
-    for (int i=0;i<4;i++) {
-        digitImageViews[i].hidden = YES;
-    }
-    if (animated) {
-        contentView.frame = CGRectOffset(contentView.frame, contentView.frame.size.width*dir, 0);
-        [UIView animateWithDuration:SLIDE_DURATION animations:^() {
-            contentView.frame = CGRectOffset(contentView.frame, -contentView.frame.size.width*dir, 0);
-        } completion:^(BOOL finished) {
-            [snapshotImageView removeFromSuperview];
-            snapshotImageView = nil;
-        }];
-    }
-}
-
-@end

+ 2 - 0
Podfile

@@ -15,6 +15,7 @@ pod 'XKKeychain', '~>1.0'
 pod 'box-ios-sdk-v2', :git => 'git://github.com/fkuehne/box-ios-sdk-v2.git' #has a logout function added
 pod 'CocoaHTTPServer', :git => 'git://github.com/fkuehne/CocoaHTTPServer.git' # has our fixes
 pod 'RESideMenu', '~>4.0.7'
+pod 'PAPasscode', '~>1.0'
 pod 'GoogleAPIClient/Drive'
 pod 'VLC-LXReorderableCollectionViewFlowLayout', '0.1.3v'
 pod 'VLC-WhiteRaccoon'
@@ -36,6 +37,7 @@ pod 'XKKeychain', '~>1.0'
 pod 'box-ios-sdk-v2', :git => 'git://github.com/fkuehne/box-ios-sdk-v2.git' #has a logout function added
 pod 'CocoaHTTPServer', :git => 'git://github.com/fkuehne/CocoaHTTPServer.git' # has our fixes
 pod 'RESideMenu', '~>4.0.7'
+pod 'PAPasscode', '~>1.0'
 pod 'GoogleAPIClient/Drive'
 pod 'VLC-LXReorderableCollectionViewFlowLayout', '0.1.3v'
 pod 'VLC-WhiteRaccoon'

+ 4 - 1
Podfile.lock

@@ -48,6 +48,7 @@ PODS:
   - OROpenSubtitleDownloader (1.2.0):
     - AFNetworking
     - xmlrpc
+  - PAPasscode (1.0)
   - RESideMenu (4.0.7)
   - TVVLCKit-unstable (3.0.0a49)
   - upnpx (1.4.0)
@@ -73,6 +74,7 @@ DEPENDENCIES:
   - ObjectiveDropboxOfficial (from `git://github.com/carolanitz/dropbox-sdk-obj-c.git`)
   - OBSlider (= 1.1.0)
   - OROpenSubtitleDownloader (from `https://github.com/orta/OROpenSubtitleDownloader.git`, commit `0509eac2`)
+  - PAPasscode (~> 1.0)
   - RESideMenu (~> 4.0.7)
   - TVVLCKit-unstable (= 3.0.0a49)
   - upnpx (~> 1.4.0)
@@ -131,6 +133,7 @@ SPEC CHECKSUMS:
   ObjectiveDropboxOfficial: e11cdf40e8965a6c24c6d6ff64905f2df43ab653
   OBSlider: 490f108007bfdd5414a38650b211fe403a95b8a0
   OROpenSubtitleDownloader: 154b8c08acbf8836b77ac259018dc8b5baef907e
+  PAPasscode: b408fb87c530cad58a554e26482e87dbb14b7bc2
   RESideMenu: f24c508404b49c667344c54aba7e590883533958
   TVVLCKit-unstable: 76643469a2fe5186589a14fbf35bdf893bba70e5
   upnpx: c695b99229e08154d23abe5c252cb64f1600f35d
@@ -140,6 +143,6 @@ SPEC CHECKSUMS:
   XKKeychain: 852ef663c56a7194c73d3c68e8d9d4f07b121d4f
   xmlrpc: 109bb21d15ed6d108b2c1ac5973a6a223a50f5f4
 
-PODFILE CHECKSUM: 141583cd82da54cc43bba4409eac6dabe5693aed
+PODFILE CHECKSUM: 7c967ad3372558a99553f8a73764e93070dc1055
 
 COCOAPODS: 1.3.1

+ 16 - 0
Resources/VLCStringsForLocalization.m

@@ -20,5 +20,21 @@ NSLocalizedString(@"SECTION_HEADER_NETWORK", nil);
 NSLocalizedString(@"THIS_FILE", nil);
 NSLocalizedString(@"NOT_SUPPORTED_FILETYPE", nil);
 NSLocalizedString(@"FILE_EXISTS", nil);
+NSLocalizedString(@"BIOMETRIC_UNLOCK", nil);
 
+//These Strings are in PAPasscode and we need to translate them
+NSLocalizedString(@"Set Passcode", nil);
+NSLocalizedString(@"Enter a passcode", nil);
+NSLocalizedString(@"Re-enter your passcode", nil);
+NSLocalizedString(@"Enter Passcode", nil);
+NSLocalizedString(@"Enter your passcode", nil);
+NSLocalizedString(@"Passcodes did not match. Try again.", nil);
+NSLocalizedString(@"Change Passcode", nil);
+NSLocalizedString(@"Enter your old passcode", nil);
+NSLocalizedString(@"Enter your new passcode", nil);
+NSLocalizedString(@"Re-enter your new passcode", nil);
+NSLocalizedString(@"Passcodes did not match. Try again.", nil);
+NSLocalizedString(@"1 Failed Passcode Attempt", nil);
+NSLocalizedString(@"%d Failed Passcode Attempts", nil);
+NSLocalizedString(@"Next", nil);
 }

+ 15 - 12
Resources/en.lproj/Localizable.strings

@@ -59,7 +59,6 @@
 "BUTTON_DOWNLOAD" = "Download";
 "BUTTON_DELETE" = "Delete";
 "BUTTON_OK" = "OK";
-"BUTTON_NEXT" = "Next";
 "BUTTON_CONTRIBUTE" = "Contribute";
 "BUTTON_CONNECT" = "Connect";
 "BUTTON_RENAME" = "Rename";
@@ -163,18 +162,23 @@
 "NO_FILES" = "No supported files";
 "DOWNLOADING" = "Downloading...";
 "REMAINING_TIME" = "Remaining time: %@";
-"ENTER_PASSCODE" = "Enter Passcode";
-"REENTER_PASSCODE" = "Re-enter Passcode";
-"PASSCODE_SET" = "Set Passcode";
-"PASSCODE_CHANGE" = "Change Passcode";
-"PASSCODE_ENTER_OLD" = "Enter your old passcode";
-"PASSCODE_ENTER_NEW" = "Enter your new passcode";
-"PASSCODE_REENTER_NEW" = "Re-enter your new passcode";
-"PASSCODES_DID_NOT_MATCH" = "Passcodes did not match. Try again.";
-"PASSCODE_FAILED_1" = "1 Failed Passcode Attempt";
-"PASSCODE_FAILED_FORMAT" = "%d Failed Passcode Attempts";
 "BIOMETRIC_UNLOCK" = "Unlock Media Library\nCancel to enter Passcode";
 
+//PAPasscode Strings that we need to localize for them
+"%d Failed Passcode Attempts" = "%d Failed Passcode Attempts";
+"1 Failed Passcode Attempt" = "1 Failed Passcode Attempt";
+"Change Passcode" = "Change Passcode";
+"Enter Passcode" = "Enter Passcode";
+"Enter a passcode" = "Enter a passcode";
+"Enter your new passcode" = "Enter your new passcode";
+"Enter your old passcode" = "Enter your old passcode";
+"Enter your passcode" = "Enter your passcode";
+"Next" = "Next";
+"Passcodes did not match. Try again." = "Passcodes did not match. Try again.";
+"Re-enter your new passcode" = "Re-enter your new passcode";
+"Re-enter your passcode" = "Re-enter your passcode";
+"Set Passcode" = "Set Passcode";
+
 "Settings" = "Settings"; // plain text key to keep compatibility with InAppSettingsKit's upstream
 "ON" = "On";
 "OFF" = "Off";
@@ -332,4 +336,3 @@
 /* New strings */
 "PROTOCOL_NOT_SELECTED" = "PROTOCOL_NOT_SELECTED";
 "Settings" = "Settings";
-

+ 22 - 10
Sources/KeychainCoordinator.swift

@@ -33,27 +33,35 @@ class KeychainCoordinator:NSObject, PAPasscodeViewControllerDelegate {
 
     private var avoidPromptingTouchOrFaceID = false
 
-    private var passcodeLockController:PAPasscodeViewController {
-        let passcodeController = PAPasscodeViewController()
-        passcodeController.delegate = self
-        return passcodeController
-    }
+    private lazy var passcodeLockController:PAPasscodeViewController = {
+        let passcodeController = PAPasscodeViewController(for: PasscodeActionEnter)
+        passcodeController!.delegate = self
+        return passcodeController!
+    }()
 
     override init() {
         super.init()
         NotificationCenter.default.addObserver(self, selector: #selector(appInForeground), name: .UIApplicationDidBecomeActive, object: nil)
     }
 
-    @objc class func setPasscode(passcode:String?) {
+    @objc class func setPasscode(passcode:String?) throws {
         guard let passcode = passcode else {
-            try? XKKeychainGenericPasswordItem.removeItems(forService: passcodeService)
+            do {
+                try XKKeychainGenericPasswordItem.removeItems(forService: passcodeService)
+            } catch let error {
+                throw error
+            }
             return
         }
         let keychainItem = XKKeychainGenericPasswordItem()
         keychainItem.service = passcodeService
         keychainItem.account = passcodeService
         keychainItem.secret.stringValue = passcode
-        try? keychainItem.save()
+        do {
+            try keychainItem.save()
+        } catch let error {
+            throw error
+        }
     }
 
     @objc func validatePasscode(completion:@escaping ()->()) {
@@ -68,6 +76,7 @@ class KeychainCoordinator:NSObject, PAPasscodeViewControllerDelegate {
 
         let navigationController = UINavigationController(rootViewController: passcodeLockController)
         navigationController.modalPresentationStyle = .fullScreen
+        navigationController.modalTransitionStyle = .crossDissolve
 
         rootViewController.present(navigationController, animated: true) {
             [weak self] in
@@ -111,8 +120,11 @@ class KeychainCoordinator:NSObject, PAPasscodeViewControllerDelegate {
     }
 
     private func passcodeFromKeychain() -> String {
-        let item = try? XKKeychainGenericPasswordItem(forService: KeychainCoordinator.passcodeService, account: KeychainCoordinator.passcodeService)
-        return item?.secret?.stringValue ?? ""
+        if let item = try? XKKeychainGenericPasswordItem(forService: KeychainCoordinator.passcodeService, account: KeychainCoordinator.passcodeService) {
+            return item.secret.stringValue
+        }
+        assert(false, "Couldn't retrieve item from Keychain! If passcodeLockEnabled we should have an item and secret")
+        return ""
     }
 
     //MARK: PAPassCodeDelegate

+ 8 - 5
Sources/VLCSettingsController.m

@@ -128,12 +128,15 @@
 
 - (void)updateForPasscode:(NSString *)passcode
 {
-    if (passcode == nil) {
-        //Set manually the value to NO to disable the UISwitch.
-        [[NSUserDefaults standardUserDefaults] setBool:NO forKey:kVLCSettingPasscodeOnKey];
+    NSError *error = nil;
+    [VLCKeychainCoordinator setPasscodeWithPasscode:passcode error:&error];
+    if (error == nil) {
+        if (passcode == nil) {
+            //Set manually the value to NO to disable the UISwitch.
+            [[NSUserDefaults standardUserDefaults] setBool:NO forKey:kVLCSettingPasscodeOnKey];
+        }
+        [self updateUIAndCoreSpotlightForPasscodeSetting:passcode != nil];
     }
-    [VLCKeychainCoordinator setPasscodeWithPasscode:passcode];
-    [self updateUIAndCoreSpotlightForPasscodeSetting:passcode != nil];
     if ([self.navigationController.presentedViewController isKindOfClass:[PAPasscodeViewController class]]) {
         [self.navigationController.presentedViewController dismissViewControllerAnimated:YES completion:nil];
     }

+ 1 - 1
VLC-iOS-Bridging-Header.h

@@ -6,6 +6,6 @@
 #import "VLCPlaylistTableViewCell.h"
 #import "VLCMediaDataSource.h"
 #import "VLCLibraryViewController.h"
-#import "PAPasscodeViewController.h"
+#import <PAPasscode/PAPasscodeViewController.h>
 #import <XKKeychain/XKKeychain.h>
 #import "VLCConstants.h"

+ 1 - 8
VLC.xcodeproj/project.pbxproj

@@ -131,7 +131,6 @@
 		7D3784C3183A9938009EE944 /* VLCStatusLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D3784BD183A9938009EE944 /* VLCStatusLabel.m */; };
 		7D3784C8183A9972009EE944 /* NSString+SupportedMedia.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D3784C5183A9972009EE944 /* NSString+SupportedMedia.m */; };
 		7D3784C9183A9972009EE944 /* UIDevice+VLC.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D3784C7183A9972009EE944 /* UIDevice+VLC.m */; };
-		7D3784CC183A99BA009EE944 /* PAPasscodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D3784CB183A99BA009EE944 /* PAPasscodeViewController.m */; };
 		7D3784E9183A9A15009EE944 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D3784E8183A9A15009EE944 /* main.m */; };
 		7D398DC11CC3E709002C999A /* VLCLocalNetworkServiceBrowserBonjour.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D398DC01CC3E709002C999A /* VLCLocalNetworkServiceBrowserBonjour.m */; };
 		7D398DC21CC3E709002C999A /* VLCLocalNetworkServiceBrowserBonjour.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D398DC01CC3E709002C999A /* VLCLocalNetworkServiceBrowserBonjour.m */; };
@@ -292,7 +291,6 @@
 		7DC54FF51C046615007B4E42 /* BasicUPnPDevice+VLC.m in Sources */ = {isa = PBXBuildFile; fileRef = DD3EABF71BE14BD6003668DA /* BasicUPnPDevice+VLC.m */; };
 		7DC54FF61C046615007B4E42 /* VLCServerBrowsingController.m in Sources */ = {isa = PBXBuildFile; fileRef = DD3EAC081BE2192A003668DA /* VLCServerBrowsingController.m */; };
 		7DC54FF71C046615007B4E42 /* UIDevice+VLC.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D3784C7183A9972009EE944 /* UIDevice+VLC.m */; };
-		7DC54FF81C046615007B4E42 /* PAPasscodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D3784CB183A99BA009EE944 /* PAPasscodeViewController.m */; };
 		7DC54FF91C046615007B4E42 /* VLCNetworkListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DDEAECCC1BDECCB800756C83 /* VLCNetworkListViewController.m */; };
 		7DC54FFA1C046615007B4E42 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D3784E8183A9A15009EE944 /* main.m */; };
 		7DC54FFB1C046615007B4E42 /* VLCHTTPConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D30F3BD183AB24C00FFC021 /* VLCHTTPConnection.m */; };
@@ -995,8 +993,6 @@
 		7D3784C5183A9972009EE944 /* NSString+SupportedMedia.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSString+SupportedMedia.m"; path = "Sources/NSString+SupportedMedia.m"; sourceTree = SOURCE_ROOT; };
 		7D3784C6183A9972009EE944 /* UIDevice+VLC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIDevice+VLC.h"; path = "Sources/UIDevice+VLC.h"; sourceTree = SOURCE_ROOT; };
 		7D3784C7183A9972009EE944 /* UIDevice+VLC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIDevice+VLC.m"; path = "Sources/UIDevice+VLC.m"; sourceTree = SOURCE_ROOT; };
-		7D3784CA183A99BA009EE944 /* PAPasscodeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PAPasscodeViewController.h; path = PAPasscode/PAPasscodeViewController.h; sourceTree = SOURCE_ROOT; };
-		7D3784CB183A99BA009EE944 /* PAPasscodeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PAPasscodeViewController.m; path = PAPasscode/PAPasscodeViewController.m; sourceTree = SOURCE_ROOT; };
 		7D3784E5183A99E1009EE944 /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Reachability.h; path = Sources/Reachability.h; sourceTree = SOURCE_ROOT; };
 		7D3784E6183A99E1009EE944 /* Reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Reachability.m; path = Sources/Reachability.m; sourceTree = SOURCE_ROOT; };
 		7D3784E8183A9A15009EE944 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Sources/main.m; sourceTree = SOURCE_ROOT; };
@@ -2493,8 +2489,6 @@
 		A7A0E9EB174BA66000162F25 /* PAPasscode */ = {
 			isa = PBXGroup;
 			children = (
-				7D3784CA183A99BA009EE944 /* PAPasscodeViewController.h */,
-				7D3784CB183A99BA009EE944 /* PAPasscodeViewController.m */,
 			);
 			name = PAPasscode;
 			sourceTree = "<group>";
@@ -2975,6 +2969,7 @@
 					7D94FCDA16DE7D1000F2623B = {
 						DevelopmentTeam = 75GAHG3SZQ;
 						LastSwiftMigration = 0920;
+						ProvisioningStyle = Automatic;
 						SystemCapabilities = {
 							com.apple.ApplicationGroups.iOS = {
 								enabled = 1;
@@ -3824,7 +3819,6 @@
 				DD3EABF81BE14BD6003668DA /* BasicUPnPDevice+VLC.m in Sources */,
 				DD3EAC091BE2192A003668DA /* VLCServerBrowsingController.m in Sources */,
 				7D3784C9183A9972009EE944 /* UIDevice+VLC.m in Sources */,
-				7D3784CC183A99BA009EE944 /* PAPasscodeViewController.m in Sources */,
 				DDEAECCD1BDECCB800756C83 /* VLCNetworkListViewController.m in Sources */,
 				7D3784E9183A9A15009EE944 /* main.m in Sources */,
 				416DEFF61FEEA76A00F4FC59 /* LayoutAnchorContainer.swift in Sources */,
@@ -3959,7 +3953,6 @@
 				7DC54FF61C046615007B4E42 /* VLCServerBrowsingController.m in Sources */,
 				417E68BA1F321EFF00DB9BB2 /* VLCActivityViewControllerVendor.m in Sources */,
 				7DC54FF71C046615007B4E42 /* UIDevice+VLC.m in Sources */,
-				7DC54FF81C046615007B4E42 /* PAPasscodeViewController.m in Sources */,
 				7DC54FF91C046615007B4E42 /* VLCNetworkListViewController.m in Sources */,
 				7DC54FFA1C046615007B4E42 /* main.m in Sources */,
 				7DC54FFB1C046615007B4E42 /* VLCHTTPConnection.m in Sources */,