3

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.

ipatch
  • 3,933
  • 8
  • 60
  • 99

2 Answers2

1

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];
        }
    }

}
ipatch
  • 3,933
  • 8
  • 60
  • 99
0

I believe your mis-using core data. It is not meant to be used like sqlite, always running always query-able. (http://cocoawithlove.com/2010/02/differences-between-core-data-and.html)

You are trying to keep a database of user but your also over complicating it. While in memory the app can use an NSMutableArray of your own objects to keep track of usernames, tabs

So you would have your class:

interface Alcoholic : NSObject

@property(nonatomic,retain)NSString * username;
@property(nonatomic,retain)NSString * pin;
@property(nonatomic,retain)NSString * tab;
@end

In the section of code that adds these it would have a mutable array

 NSMutableArray * alcoholics = [[NSMutableArray alloc]init];

- (IBAction)processLogin:(id)sender {

int i = 0;
while (i<alcoholics.count)
{
 Aloholic = [alcoholics objectAtIndex:i];
if(self.textFieldUsername.text == Aloholic.username)
   NSLog(@"Username may exist, %@",count);
}

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

etc...

Since Im sure your next question is how to make it persistent and thats where core data comes into play.

in your app delegate get the alcoholics array and save that to core data when the app opens and closes

-(void)save
{
     //use core data to save needed data persitently

     self.Values = [NSEntityDescription
                       insertNewObjectForEntityForName:@"processLoginClass" 
                       inManagedObjectContext:[self managedObjectContext]];

          self.Values.alcoholics =  self.processLoginClass.alcoholics;

     }

     NSError *error;
     if (![[self managedObjectContext] save:&error]) 
     {
          NSLog(@"Couldn't save state information: %@", [error localizedDescription]);
     }
}

-(void)load
{
     //use core data to load needed data 

     NSError *error;
     NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
     NSEntityDescription *entity = [NSEntityDescription entityForName:@"Values" 
                                               inManagedObjectContext:[self managedObjectContext]];
     [fetchRequest setEntity:entity];

     NSArray *fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
     for (processLoginClass *info in fetchedObjects) 
     {
          [self.processLoginClass setAlcholics:info.alcholics];
     }      
}
owen gerig
  • 6,165
  • 6
  • 52
  • 91