如何使用fmdblogin页面?
我有一个login页面,有2个用户名和密码的文本框和几个button。 我想知道如何使用fmdb检查数据库中是否存在用户名/密码组合? 我也有另一个用于用户注册页面的viewcontroller,有4个用户名,密码,电子邮件,联系号码的文本框,还有一个button可以将input的文本input到数据库中。 如何将input的文本保存到数据库的4个字段中? 提前致谢。 这是我的代码:我成功地将数据input到数据库中,在registerViewController中,但是如果用户忘记密码和/或用户名,我想input代码到“btnforgot”(忘记密码)操作中。 我已经在loginViewController中取得了一些成功,至于检查数据库中的用户名和密码是否与数据库中的数据相同,但是我想我缺less一些代码。
LOGINVIEW #import "loginViewController.h" #import "carTypeViewController.h" #import "registerViewController.h" #import "FMDatabase.h" #import "AppDelegate.h" #import "FMDatabaseAdditions.h" @interface loginViewController () @end @implementation loginViewController @synthesize lblPass,lblUserName,txtPass,txtUser;
– (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 如果(self){//自定义初始化}返回自我; }
- (void)viewDidLoad { self.title = @"Enter Credentials"; username = [[NSMutableArray alloc]init]; password = [[NSMutableArray alloc]init]; [super viewDidLoad]; // Do any additional setup after loading the view from its nib. } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (IBAction)btnLogin:(id)sender { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docsPath = [paths objectAtIndex:0]; NSString *path = [docsPath stringByAppendingPathComponent:@"contacts.db"]; FMDatabase *database = [FMDatabase databaseWithPath:path]; [database open]; BOOL success = NO; NSInteger count = [database intForQuery:@"select count(*) from RegMembers where USERNAME = ? and PASSWORD = ?", username, password]; if ([txtUser.text length] == 0 || [txtPass.text length]== 0){ UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error" message:@"Kindly enter details in all fields" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; [alert show]; } else if (count > 0) { success = YES; UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Welcome" message:@"Login successful" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; [alert show]; carTypeViewController *car = [[carTypeViewController alloc]initWithNibName:@"carTypeViewController" bundle:nil]; [self.navigationController pushViewController:car animated:YES]; } else { UIAlertView *alert1 = [[UIAlertView alloc]initWithTitle:@"Kindly enter the correct credentials" message:@"Entered username or password is incorrect" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; [alert1 show]; txtUser.text=@""; txtPass.text=@""; } [database close]; } -(IBAction)removeKeyboard { [self.txtUser resignFirstResponder]; [self.txtPass resignFirstResponder]; } - (IBAction)btnSignUp:(id)sender { registerViewController *reg = [[registerViewController alloc]initWithNibName:@"registerViewController" bundle:nil]; [self.navigationController pushViewController:reg animated:YES]; } - (IBAction)btnExit:(id)sender { exit(1); } - (IBAction)btnForgotPass:(id)sender { } @end REGISTERVIEW - (void)viewDidLoad { self.title = @"Create Account"; [super viewDidLoad]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docsPath = [paths objectAtIndex:0]; NSString *path = [docsPath stringByAppendingPathComponent:@"contacts.db"]; FMDatabase *database = [FMDatabase databaseWithPath:path]; [database open]; [database executeUpdate:@"create table if not exists RegMembers (ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT DEFAULT 0, USERNAME TEXT UNIQUE NOT NULL , PASSWORD TEXT NOT NULL , EMAIL TEXT NOT NULL , NUMBER TEXT NOT NULL)"]; [database close]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } -(IBAction)removeKeyboard { [self.txtUname resignFirstResponder]; [self.txtPass resignFirstResponder]; [self.txtEmail resignFirstResponder]; [self.txtNumber resignFirstResponder]; } - (IBAction)btnUAcount:(id)sender { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docsPath = [paths objectAtIndex:0]; NSString *path = [docsPath stringByAppendingPathComponent:@"contacts.db"]; FMDatabase *database = [FMDatabase databaseWithPath:path]; if ([txtUname.text length] == 0 || [txtPass.text length]== 0 || [txtEmail.text length]== 0 || [txtNumber.text length]== 0) { UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error" message:@"Kindly enter details in all fields" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; [alert show]; } else { if ([database open]) { [database executeUpdate:@"insert into RegMembers(username, password, email, number) values(?,?,?,?)", [NSString stringWithFormat: @"%@",txtUname.text],[NSString stringWithFormat:@"%@",txtPass.text],[NSString stringWithFormat:@"%@",txtEmail.text], [NSString stringWithFormat:@"%@",txtNumber.text],nil]; if (1) { NSLog(@"contact added"); self.txtUname.text = @""; self.txtPass.text = @""; self.txtEmail.text = @""; self.txtNumber.text = @""; } else { NSLog(@"failed to add contact"); } } [database close]; UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Registeration succesful" message:@"Thanks for choosing edmunds" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; [alert show]; [self.navigationController popViewControllerAnimated:YES]; }
如果您想检查用户名/密码组合是否在您的数据库中,您可以:
#import "FMDatabaseAdditions"
然后你可以看到用户名/密码组合是否符合成功login的条件:
BOOL success = NO; NSInteger count = [database intForQuery:@"select count(*) from RegMembers where USERNAME = ? and PASSWORD = ?", username, password]; if (count > 0) success = YES;
话虽如此,我有一些从微不足道的观察到批判的观察:
-
现在你总是报告“添加联系人”。 你应该确定插入是否成功。 您可以通过检查
executeUpdate
方法返回的值来执行此操作(如果成功则返回YES
,如果INSERT
失败则返回NO
)。 -
使用
PRIMARY KEY AUTOINCREMENT
键时,不应使用DEFAULT 0
。 首先,我认为不会做任何事情(不pipe从哪里开始)。 其次,即使这样做,使用零也会非常糟糕,因为调用SQLitesqlite3_last_insert_rowid
FMDB的lastInsertRowId
对数字键使用零值来指定错误。 所以,不要使用零。 -
更重要的是,你永远不应该在设备上存储未encryption的密码。 (即使您不关心应用程序的安全性,太多的用户会重复使用密码,所以您要确保不会成为泄露密码的可能方式。)
至less要将密码存储在数据库中时进行encryption,然后在login时encryption用户提供的密码,并比较两个encryption密码。 如果您想查看一些可用的encryption服务,请参阅“ encryption服务指南” 。
-
话虽如此,你甚至可能不想自己编写任何密码encryption代码(正确地做这件事不是微不足道的)。
使用iOS钥匙串可能会更好。 苹果公司的主题是WWDC 2013video保护与钥匙链的秘密 。
例如,要保存与用户ID关联的密码,电子邮件地址和号码,可以执行如下操作:
// see if the userid already exists NSDictionary* query = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService : @"com.domain.app", (__bridge id)kSecAttrAccount : self.useridTextField.text, (__bridge id)kSecMatchLimit : (__bridge id)kSecMatchLimitOne, (__bridge id)kSecReturnData : @NO}; OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL); if (status == errSecSuccess) { [[[UIAlertView alloc] initWithTitle:nil message:@"That userid is already registered" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; return; } // create payload of secret data NSDictionary *secret = @{@"password" : self.passwordTextField.text ?: [NSNull null], @"email" : self.emailTextField.text ?: [NSNull null], @"number" : self.numberTextField.text ?: [NSNull null]}; NSData *data = [NSKeyedArchiver archivedDataWithRootObject:secret]; // create keychain query query = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService : @"com.domain.app", (__bridge id)kSecAttrAccount : self.useridTextField.text, (__bridge id)kSecValueData : data}; // add data associated with the userid in the keychain status = SecItemAdd((__bridge CFDictionaryRef)query, NULL); NSAssert(status == errSecSuccess, @"%s: SecItemAdd error: %lu", __FUNCTION__, (unsigned long)status);
那么,当你想login时,你可以做一些事情:
BOOL success = NO; NSDictionary* query = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService : @"com.domain.app", (__bridge id)kSecAttrAccount : self.useridTextField.text, (__bridge id)kSecMatchLimit : (__bridge id)kSecMatchLimitOne, (__bridge id)kSecReturnData : @YES}; CFTypeRef typeRef; OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &typeRef); // if we found keychain entry for that userid, check the password if (status == noErr) { NSDictionary *dictionary = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)typeRef]; NSAssert(dictionary, @"%s: unarchiveObjectWithData failed: %@", __FUNCTION__, (__bridge NSData *)typeRef); NSString *password = dictionary[@"password"]; if ([self.passwordTextField.text isEqualToString:password]) success = YES; CFRelease(typeRef); } // if we didn't succeed for any reason, tell the user if (!success) { [[[UIAlertView alloc] initWithTitle:nil message:@"Login failed" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil] show]; }