How to insert only one username and password in SQLite database? - iphone

I have an application where I have two textfields and a button. In the first textfield I am entering the username of the user and in the second textfield I am entering the password of the user. When the user enters the username and password and click on create user button a backend api is called which will register the username and password of the user and at the time I want to enter the username and password of the user in local SQLite databse in encrypted format.
When a user is registered the username of that particular user should get displayed in the first textfield and it should not be editable and password field should be editable. Only one user is allowed to be registered for the entire application.

Don't use a sqlite dbs to store user credentials. With reverse engineering it is fairly simple to get to the data. This because you probably have some value in your program you use to encrypt/decrypt the password. For security purposes, please use the keychain. There are several projects on github which makes it very easy to use the keychain. There is no more secure way for saving credentials then the keychain, so please use that to store your credentials!!!

If I understood your requirement correctly, You can follow the below guideline.
Before inserting the data to the table, You can check if any record is added to the table.
If the count is 0, you can proceed to insert the record, else you can prompt the error.
I think this will be the simplest way to do this.

First step is to check the database exist in resource folder and create database:-
1)
-(void)checkAndCreateDatabase{
databaseName = #"databasename.sql";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
BOOL success;
// Create a FileManager object, we will use this to check the status of the database and to copy it over if required
NSFileManager *fileManager = [NSFileManager defaultManager];
// Check if the database has already been created in the users filesystem
success = [fileManager fileExistsAtPath:databasePath];
// If the database already exists then return without doing anything
if(success) {
return;
}
// If not then proceed to copy the database from the application to the users filesystem
// Get the path to the database in the application package
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}
2) call the function to retrieve the data:-
-(NSMutableArray *) readFromDatabase:(NSString *)query{
// Setup the database object
sqlite3 *database;
// Init the animals Array
returnArray = [[NSMutableArray alloc] init];
NSString *readCommand= query;
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
const char *sqlStatement = [readCommand UTF8String];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
[returnArray addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)]];
[returnArray addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)]];
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
return returnArray;
}
3) check for the retrun array is empty or nil then call the insert function defined at step
4) Insert into the database
-(void)insertIntoDatabase:(NSString *)username:(NSString *)password{
// Setup the database object
sqlite3 *database;
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
NSString *insertCommand=#"Insert into tableName values(username,password)";
const char *sqlStatement = [insertCommand UTF8String];
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {}
sqlite3_finalize(compiledStatement);
}
// Release the compiled statement from memory
}
sqlite3_close(database);
}

You can use NSUserDefaults saving locally it. following code is for saving data.
perf = [NSUserDefaults standardUserDefaults];
[perf setObject:#"1" forKey:#"remember"];
[perf setObject:emailAddresTextField.text forKey:#"email"];
[perf setObject:passwordTextField.text forKey:#"password"];
[perf synchronize];
And for retrieving data use following code
perf=[NSUserDefaults standardUserDefaults];
NSString *remString = [perf stringForKey:#"remember"];
if ([remString isEqualToString:#"1"]) {
emailAddresTextField.text=[perf stringForKey:#"email"];
passwordTextField.text = [perf stringForKey:#"password"];
[rememberBtn setTag:1];
[rememberBtn setImage:[UIImage imageNamed:#"on_radioButton.png"] forState:0];
}

Related

Insert data in sqlite table dynamically not working

I want to insert the data in a SQLite table login when a button is clicked, the problem is that when I click on the register button data is getting stored in variable but not in database table, and When I try to statically pass the value the data will be insert but When i trying to dynamically store data then not work.
Here is my code. Please go through it and help to solve this issue.
NSString *path;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask ,YES);
path = [paths objectAtIndex:0];
dbName = [[NSString alloc] initWithString:[path stringByAppendingPathComponent:#"mnc.sqlite"]];
NSFileManager *fileMgr = [NSFileManager defaultManager];
if([fileMgr fileExistsAtPath:dbName]== NO)
{
const char *dbPath = [dbName UTF8String];
if (sqlite3_open(dbPath,&connectionDB)==SQLITE_OK)
{
char *errMsg;
const char *sql_stmt = " create table if not exists login(user_name text ,password text)";
if (sqlite3_exec(connectionDB,sql_stmt,NULL,NULL,&errMsg))
{
printf("\n fail to create table ");
}
sqlite3_close(connectionDB);
}
else
{
NSLog(#"fail to open create database");
}
}
[fileMgr release];
if(sqlite3_prepare_v2(connectionDB, query ,-1, &statment,NULL) == SQLITE_OK)
{
sqlite3_bind_text(statment,1,"cc", -1,SQLITE_TRANSIENT);
sqlite3_bind_text(statment,2,"sa",-1,SQLITE_TRANSIENT);
NSLog(#"aadd");
}
if (sqlite3_step(statment)== SQLITE_DONE)
{
NSLog(#"This should be real error checking!");
sqlite3_finalize(statment);
}
It is quite complex to work with sqlite, thats why I use fmdb this will simplify the work.
This is an Objective-c wrapper around SQLite
Hope this helps.

Not able to insert data in to sqlite table

I am new to iphone development,i was trying to insert the data in a sqlite table .but data is not inserted in the table.there was no error on the console.
NSString *string1=#"Test";
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"TestData" ofType:#"sqlite"];
if(sqlite3_open([filePath UTF8String], &database) == SQLITE_OK)
{
sqlite3_stmt *compiledStatement=nil;
char * sql = "insert into Test (title,summary,question,choice,answer) values (?,?,?,?,?)";
if (sqlite3_prepare_v2(database, sql, -1, &compiledStatement, NULL) == SQLITE_OK)
{
{
sqlite3_bind_text(compiledStatement, 1, [string1 UTF8String], -1,SQLITE_TRANSIENT);
sqlite3_bind_text(compiledStatement, 2,[string1 UTF8String] , -1,SQLITE_TRANSIENT);
sqlite3_bind_text(compiledStatement, 3, [string1 UTF8String], -1,SQLITE_TRANSIENT);
sqlite3_bind_text(compiledStatement, 4, [string1 UTF8String], -1,SQLITE_TRANSIENT);
sqlite3_bind_text(compiledStatement, 5, [string1 UTF8String], -1,SQLITE_TRANSIENT);
if(sqlite3_step(compiledStatement) != SQLITE_DONE )
{
NSLog( #"Error: %s", sqlite3_errmsg(database) );
}
else {
NSLog( #"Insert into row id = %d", sqlite3_last_insert_rowid(database));
}
}
As your database in resource bundle you are trying to modify and update it. The better approach would be place your database first time in documents directory of sandbox and then perform operation on that database.
Here is the method using which you can move your database to documents directory of your application's sandbox. This method should be called only once while using database operation.(because only first time we need to place it at that location, other times we just need to access it).
Code :
// Name : configureDatabase:
// Description : Method configures the database with new name.
// Arguements : NSString : Databse file name
// Retrun : None
-(void) configureDatabase:(NSString *)newDatabaseName
{
// Get the path to the documents directory and append the databaseName
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [[documentsDir stringByAppendingPathComponent:newDatabaseName]retain];
// Execute the "checkAndCreateDatabase" function
[self checkAndCreateDatabase:databasePath];
}
// Name : checkAndCreateDatabase:
// Description : Method checks and creates the database file at the given path if its not present.
// Arguements : NSString : file path.
// Retrun : None.
-(void) checkAndCreateDatabase:(NSString *)dbPath
{
// Check if the SQL database has already been saved to the users phone, if not then copy it over
BOOL success;
// Create a FileManager object, we will use this to check the status
// of the database and to copy it over if required
NSFileManager *fileManager = [NSFileManager defaultManager];
// Check if the database has already been created in the users filesystem
success = [fileManager fileExistsAtPath:dbPath];
// If the database already exists then return without doing anything
if(success)
{
return;
}
// If not then proceed to copy the database from the application to the users filesystem
// Get the path to the database in the application package
NSString *databasePathFromApp=[[NSBundle mainBundle] pathForResource:#"TestData" ofType:#"sqlite"];
// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:dbPath error:nil];
}
Also note that if we are using database so it is good practice to locate it first in some directory from where user can take backup. Documents directory of sandbox is one of these backup ready directory.
Thanks,

Database Application not work properly

In my application i open the database many time in one loop and then again i open the database it will not execute if (sqlite3_open([[self getDBPath] UTF8String], &database) == SQLITE_OK) this statement so my application doesnt work....
-(NSString *)getDBPath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:#"BasicGreetings.sqlite"];
}
-(void) fillimage:(NSInteger)imgno
{
testAppDelegate *appDelg = (testAppDelegate *)[[UIApplication sharedApplication]delegate];
sqlite3 *database= nil;
if (sqlite3_open([[self getDBPath] UTF8String], &database) == SQLITE_OK)
{
const char *sql = "select setflag from Tblsetflag where imgNo = ?";
sqlite3_stmt *selectStmt = nil;
if (sqlite3_prepare_v2(database, sql, -1, &selectStmt, NULL) == SQLITE_OK)
{
sqlite3_bind_int(selectStmt, 1,imgno);
while (sqlite3_step(selectStmt) == SQLITE_ROW)
{
appDelg.a = sqlite3_column_int(selectStmt, 0);
NSLog(#"%d",appDelg.a);
}
}
}
sqlite3_close(database);
}
Can you post the code to getDBPath, I suspect it can't find the file... check that value you return from that method (run in the simulator) and browse the simulator documents directory in Finder and verify the file exists.
Don't open and close your database on every pass through your -fillimage: method. You really should open it once at the start of your application (or when your application has become active from the background) and close it when your application exits or goes to the background.
You also never finalize your prepared statement, which may be leading to the sqlite3_close() failing. Again, you may want to create a prepared statement once, then reset it every time you run that method and finalize it before the SQLite database is closed.

Data insertion problem in sqlite

I am inserted first record in sqlite, and when i am trying to add another it shows "Database Locked" error.
the code is:
- (void) addRecord:(NSMutableDictionary *)recordDict
{
if(addStmt == nil) {
const char *sql = "insert into Product(ProID, BarCode , ProductName ) Values(?,?,?)";
if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
NSAssert1(0, #"Error while creating add statement. '%s'", sqlite3_errmsg(database));
}
NSInteger recordId = [[recordDict objectForKey:#"ProID"] intValue];
NSLog(#"%d",recordId);
sqlite3_bind_int(addStmt, 1,recordId);
sqlite3_bind_text(addStmt, 2, [[recordDict objectForKey:#"BarCode"] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(addStmt, 3, [[recordDict objectForKey:#"ProductName"] UTF8String], -1, SQLITE_TRANSIENT);
if(SQLITE_DONE != sqlite3_step(addStmt))
NSAssert1(0, #"Error while inserting data. '%s'", sqlite3_errmsg(database));
else
{//SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid
rowID = sqlite3_last_insert_rowid(database);
NSLog(#"last inserted rowId = %d",rowID);
//Reset the add statement.
sqlite3_reset(addStmt);
}
}
Nothing in your code jumps out at me. If you are getting "Database Locked" then that means you have an open transaction that is locking the database. This could be in your app (in another thread perhaps) or in another app that is also accessing the same database.
"Database Locked" means the database is not writable, two reasons for this -
1) You forget to finlalize your previous compiled statement or forgot to close the database try this in your previous query -
sqlite3_finalize(compiledStatement);
sqlite3_close(database);
2) Are you copying the database in Documents directory before using it? You can't modify the database in bundle itself. Here is the code to copy the database in documents directory.
-(void) checkAndCreateDatabase{
// Check if the SQL database has already been saved to the users phone, if not then copy it over
BOOL success;
// Create a FileManager object, we will use this to check the status
// of the database and to copy it over if required
NSFileManager *fileManager = [NSFileManager defaultManager];
// Check if the database has already been created in the users filesystem
success = [fileManager fileExistsAtPath:databasePath];
// If the database already exists then return without doing anything
if(success) return;
// If not then proceed to copy the database from the application to the users filesystem
// Get the path to the database in the application package
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
// Copy the database from the package to the users filesystem
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
[fileManager release];
}
Here is how to get database path -
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [[documentsDir stringByAppendingPathComponent:databaseName] retain];
NSLog(#"%#",databasePath);

iphone xcode sqlite3_open remote host

i try to get a connection my server, with the sqlite3_open command!
my question...is it possible to that? i got the following code...
// Get the path to the documents directory and append the databaseName
databaseName = #"AnimalDatabase.sql";
NSString *serverpath = #"http://localhost/app/";
databasePath = [serverpath stringByAppendingPathComponent:databaseName];
and then this here
-(void) readAnimalsFromDatabase {
// Setup the database object
sqlite3 *database;
// Init the animals Array
animals = [[NSMutableArray alloc] init];
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
const char *sqlStatement = "select * from animals";
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
NSString *aDescription = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
NSString *aImageUrl = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];
// Create a new animal object with the data from the database
Animal *animal = [[Animal alloc] initWithName:aName description:aDescription url:aImageUrl];
// Add the animal object to the animals Array
[animals addObject:animal];
[animal release];
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
any suggestion??
Where you get the idea that SQLite can open database from URL??
It can open files only (or, create temporary db in memory).
The answer is just NO, there are lot of mistakes in your code anyway. For example:
databaseName = #"AnimalDatabase.sql";
Where did you get this. iPhone is working with sqlite database, it has nothing in common with sql files:)