0
2012-05-08 21:33:34.279 Passwordapp[384:fb03] Setting up a Fetched Results Controller for the Entity named Role
2012-05-08 21:33:34.292 Passwordapp[384:fb03] There's stuff in the database so skipping the import of default data
2012-05-08 21:33:34.293 Passwordapp[384:fb03] -[LoginViewController viewControllers]: unrecognized selector sent to instance 0x8e7d750
2012-05-08 21:33:34.301 Passwordapp[384:fb03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[LoginViewController viewControllers]: unrecognized selector sent to instance 0x8e7d750'
*** First throw call stack:
(0x1359022 0x1742cd6 0x135acbd 0x12bfed0 0x12bfcb2 0x2db6 0x390386 0x391274 0x3a0183 0x3a0c38 0x394634 0x1f93ef5 0x132d195 0x1291ff2 0x12908da 0x128fd84 0x128fc9b 0x390c65 0x392626 0x25cd 0x2535)
terminate called throwing an exception(lldb)
#import <UIKit/UIKit.h>
#import "passconst.h"
@interface LoginViewController : UIViewController <UITextFieldDelegate>
@property (nonatomic) BOOL pinValidated;
@end
#import "LoginViewController.h"
#import "KeychainWrapper.h"
@implementation LoginViewController
@synthesize pinValidated;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
// Helper method to congregate the Name and PIN fields for validation.
- (BOOL)credentialsValidated
{
NSString *name = [[NSUserDefaults standardUserDefaults] stringForKey:USERNAME];
BOOL pin = [[NSUserDefaults standardUserDefaults] boolForKey:PIN_SAVED];
if (name && pin) {
return YES;
} else {
return NO;
}
}
- (void)presentAlertViewForPassword
{
// 1
BOOL hasPin = [[NSUserDefaults standardUserDefaults] boolForKey:PIN_SAVED];
// 2
if (hasPin) {
// 3
NSString *user = [[NSUserDefaults standardUserDefaults] stringForKey:USERNAME];
NSString *message = [NSString stringWithFormat:@"What is %@'s password?", user];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Enter Password"
message:message
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"Done", nil];
// 4
[alert setAlertViewStyle:UIAlertViewStyleSecureTextInput]; // Gives us the password field
alert.tag = kAlertTypePIN;
// 5
UITextField *pinField = [alert textFieldAtIndex:0];
pinField.delegate = self;
pinField.autocapitalizationType = UITextAutocapitalizationTypeWords;
pinField.tag = kTextFieldPIN;
[alert show];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Setup Credentials"
message:@"Secure your Password list!"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"Done", nil];
// 6
[alert setAlertViewStyle:UIAlertViewStyleLoginAndPasswordInput];
alert.tag = kAlertTypeSetup;
UITextField *nameField = [alert textFieldAtIndex:0];
nameField.autocapitalizationType = UITextAutocapitalizationTypeWords;
nameField.placeholder = @"Name"; // Replace the standard placeholder text with something more applicable
nameField.delegate = self;
nameField.tag = kTextFieldName;
UITextField *passwordField = [alert textFieldAtIndex:1]; // Capture the Password text field since there are 2 fields
passwordField.delegate = self;
passwordField.tag = kTextFieldPassword;
[alert show];
}
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (alertView.tag == kAlertTypePIN) {
if (buttonIndex == 1 && self.pinValidated) { // User selected "Done"
[self performSegueWithIdentifier:@"Loginsegue" sender:self];
self.pinValidated = NO;
} else { // User selected "Cancel"
[self presentAlertViewForPassword];
}
} else if (alertView.tag == kAlertTypeSetup) {
if (buttonIndex == 1 && [self credentialsValidated]) { // User selected "Done"
[self performSegueWithIdentifier:@"Loginsegue" sender:self];
} else { // User selected "Cancel"
[self presentAlertViewForPassword];
}
}
}
#pragma mark - Text Field + Alert View Methods
- (void)textFieldDidEndEditing:(UITextField *)textField
{
// 1
switch (textField.tag) {
case kTextFieldPIN: // We go here if this is the 2nd+ time used (we've already set a PIN at Setup).
NSLog(@"User entered PIN to validate");
if ([textField.text length] > 0) {
// 2
NSUInteger fieldHash = [textField.text hash]; // Get the hash of the entered PIN, minimize contact with the real password
// 3
if ([KeychainWrapper compareKeychainValueForMatchingPIN:fieldHash]) { // Compare them
NSLog(@"** User Authenticated!!");
self.pinValidated = YES;
} else {
NSLog(@"** Wrong Password :(");
self.pinValidated = NO;
}
}
break;
case kTextFieldName: // 1st part of the Setup flow.
NSLog(@"User entered name");
if ([textField.text length] > 0) {
[[NSUserDefaults standardUserDefaults] setValue:textField.text forKey:USERNAME];
[[NSUserDefaults standardUserDefaults] synchronize];
}
break;
case kTextFieldPassword: // 2nd half of the Setup flow.
NSLog(@"User entered PIN");
if ([textField.text length] > 0) {
NSUInteger fieldHash = [textField.text hash];
// 4
NSString *fieldString = [KeychainWrapper securedSHA256DigestHashForPIN:fieldHash];
NSLog(@"** Password Hash - %@", fieldString);
// Save PIN hash to the keychain (NEVER store the direct PIN)
if ([KeychainWrapper createKeychainValue:fieldString forIdentifier:PIN_SAVED]) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:PIN_SAVED];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(@"** Key saved successfully to Keychain!!");
}
}
break;
default:
break;
}
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.pinValidated = NO;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self presentAlertViewForPassword];
[super viewDidAppear:animated];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:vc animated:YES];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
@end
我想加載登錄屏幕,然後調用一個標籤控制器我該如何做到這一點 –