Search code examples
ioscore-datakeychainnsfetchrequestnsentitydescription

iOS - How to create a login process using keychain / Core Data?


I am creating a multi-user iPhone app, and I am trying to finish up the coding for the user login in process. I can successfully create an account, and store the data the user inputs into the Core Data DB, and the pin (password) into the Keychain, so now I am trying to complete the login process. The following code listed below is what I have so far, and I am wondering what I need to do to complete the login process.

- (IBAction)processLogin:(id)sender {

// hide keyboard
[_textFieldUsername resignFirstResponder];
[_textFieldPin resignFirstResponder];


// First - make activity indicator visible, then start animating, then turn of wrong user / pin label
_welcomeActivityIndicator.hidden = FALSE;
[_welcomeActivityIndicator startAnimating];
[_wrongUserPin setHidden:YES];

// check if username and pin text fields are populated
if ([_textFieldUsername.text length ] == 0 &&  [_textFieldPin.text length ] == 0)
{
    [_welcomeActivityIndicator stopAnimating];
    [_wrongUserPin setHidden:NO];   
}

// CORE DATA    
NSFetchRequest *request= [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Account" inManagedObjectContext:_managedObjectContext];
NSPredicate *predicate =[NSPredicate predicateWithFormat:@"username=%@",self.textFieldUsername.text];

//check pin
Account *pinAccount = [[Account alloc] init];
[pinAccount.password isEqualToString:_textFieldPin.text];

[request setEntity:entity];
[request setPredicate:predicate];

NSError *error = nil;

NSArray *array = [_managedObjectContext executeFetchRequest:request error:&error];
if (array != nil) {
    NSUInteger count = [array count]; // may be 0 if the object has been deleted.
    NSLog(@"Username may exist, %@",count);
}

else {
    NSLog(@"Username does not exist.");
}

// TODO - put this in proper place - play audio bell if user logs in correctly
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) @"Glass", CFSTR("aiff"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);

// TODO - put this in proper place - Load ViewControllerHome
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
ViewControllerHome *home = (ViewControllerHome *)[storyboard instantiateViewControllerWithIdentifier:@"Home"];
[self presentModalViewController:home animated:YES];

}

The Account and AccountBase class files m and h look like the following:

Account.h http://pastie.org/4149299

Account.m http://pastie.org/4149296

AccountBase.h http://pastie.org/4149301

AccountBase.m http://pastie.org/4149302

I would appreciate any ideas or thoughts, and thanks for reading.


Solution

  • I was able to complete the login process with the following code.

    - (IBAction)processLogin:(id)sender {
    
    // hide keyboard
    [_textFieldUsername resignFirstResponder];
    [_textFieldPin resignFirstResponder];
    
    
    // First - make activity indicator visible, then start animating, then turn of wrong user / pin label
    _welcomeActivityIndicator.hidden = FALSE;
    [_welcomeActivityIndicator startAnimating];
    [_wrongUserPin setHidden:YES];
    
    // check if username and pin text fields are populated
    if ([_textFieldUsername.text length ] == 0 &&  [_textFieldPin.text length ] == 0)
    {
        [_welcomeActivityIndicator stopAnimating];
        [_wrongUserPin setHidden:NO];   
    }
    
    // CORE DATA
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Account" inManagedObjectContext:_managedObjectContext];
    
    // set entity for request
    [request setEntity:entity];
    
    // filter results using a predicate
    NSPredicate *pred =[NSPredicate predicateWithFormat:(@"username = %@"), _textFieldUsername.text];
    
    // set predicate for the request
    [request setPredicate:pred];
    
    NSError *error = nil;
    
    // store DB usernames in results array
    NSArray *results = [_managedObjectContext executeFetchRequest:request error:&error];
    
    NSLog(@"The returned results are %@",results);
    
    
    // check text field against results stored in DB
    for (Account *anAccount in results) {
        if ([anAccount.username isEqualToString:_textFieldUsername.text]){
            NSLog(@"Your username exists");
            if ([anAccount.password isEqualToString:_textFieldPin.text]){
                NSLog(@"Your pin is correct");
    
                // TODO - put this in proper place - play audio bell if user logs in correctly
                CFBundleRef mainBundle = CFBundleGetMainBundle();
                CFURLRef soundFileURLRef;
                soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) @"Glass", CFSTR("aiff"), NULL);
                UInt32 soundID;
                AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
                AudioServicesPlaySystemSound(soundID);
    
                // TODO - put this in proper place - Load ViewController(Root)Home
                if([anAccount.username isEqualToString:@"root"])
                {
                    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
                    ViewControllerRootHome *roothome = (ViewControllerRootHome *)[storyboard instantiateViewControllerWithIdentifier:@"rootHome"];
                    [self presentModalViewController:roothome animated:YES];
                }
                else {
                    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
                    ViewControllerHome *home = (ViewControllerHome *)[storyboard instantiateViewControllerWithIdentifier:@"Home"];
                    [self presentModalViewController:home animated:YES];
                }
            }
            else {
                NSLog(@"Your pin is wrong");
                [_welcomeActivityIndicator stopAnimating];
                [_wrongUserPin setHidden:NO];
                }
            }
        else {
            NSLog(@"Your username was not found");
            [_welcomeActivityIndicator stopAnimating];
            [_wrongUserPin setHidden:NO];
            }
        }
    
    }