Reading/Writing an online SQLite Database iPhone - iphone

I've got a database full of usernames and passwords etc. But i need to able to either download a fresh copy of the database every time the user opens the applciation, or even better, read/write to the database using the internet, which is the most practical solution.
This is currently the code that i am using to read and write to the database locally, this was mainly for the purpose of creating the functions and rules that will be used to read/write to the database online.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
databaseName = #"UserDatabase.sql";
// 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:databaseName];
// Execute the "checkAndCreateDatabase" function
[self checkAndCreateDatabase];
[self readNamesFromDatabase];
// Query the database for all username,pass,email records and construct the three different array's for each.
[registerForm setHidden:YES];
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
return YES;
}
Thank you in advance!

Since SQLite version is specifically designed for using in iPhone, so the idea of online SQLite is totally wrong.. since SQLite file is stored in iPhone only...
One of the option of updating your SQLite database is you can program your code to update database when your app starts or on update button. Doing this you can Read/Write your database... and your database will be stored on iPhone...

Related

How to display data if the device has no network connection?

I have a situation where I'm presenting data in a UITableView using NSJSONSerialization from an external source. I also have to show this data if the device is in offline mode. What is the best approach to doing this? Do I need an internal db to store the data, check for wifi and if it's unavailable present the local data?
thanks for any help or tutorials you may know of.
I have a similar requirement for an app I am working on. I am pulling the data from parse.com (remote objects) and put the data into core data (local objects). When presenting a table view, I run the parse.com query in the background, which pulls the data and puts it into core data. The table views use NSFetchedResultsController so when changes occur to the core data (local) objects, the table view is updated as the data is retrieved. If off line, nothing is retrieved, so the table view does not update, but is presenting the last update of the objects.
Yes . You can make local database to do that thing.
You can check the wifi status. If net connection is available than display data from the external source and if net connection is not available than display data from the local database.
When you retrieve data from external source when you are online store it locally.
Next time when your app is launched:
Check for network connection
If network connection is available retrieve data and re-write the old content
If network connection is not available use the locally stored data
Data can be stored in plist, database file or as an text file.
You can use a CoreData database i.e. and update the data every time you connect. If you cannot connect, just show the old data.
How to use and how to check WiFi connection SO is offering more than enought content ;)
you can store the data in plist if it is not too much.
-(void)Writetoplist:(NSMutableDictionary*)LoginDetails
{
{
//////// This is used to delete the plist file if exist //////
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
plistPath = [documentsDirectory stringByAppendingPathComponent:#"LoginDetails.plist"];
NSError *error;
if(![[NSFileManager defaultManager] removeItemAtPath:plistPath error:&error])
{
//TODO: Handle/Log error
}
/// to write the SP Details in plist file
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
documentsDirectory = [paths objectAtIndex:0];
// get the path to our plist ("Documents/foo.plist")
plistPath = [documentsDirectory stringByAppendingPathComponent:#"LoginDetails.plist"];
[LoginDetails writeToFile:plistPath atomically:YES];
}
}

what is the best way to take the backup of data of sqlite3 database of iphone application?

i want to take the backup of all the data in the database of my iphone app in dropbox and restore it later.here the main problem is there is too much data in the app so if i am using sql queries to fetch data from sqlite3 database and storing it into the file and again reading data from that file and inserting it to database.can anyone suggest that how can i improve that or what is the best way to do that?
I presume that you mean that you want to be able to restore the data after user has somehow deleted the application and re-installed it again. Since each application has its influence inside the bounds of its sandbox, the only sane option would be to use server. In regards to simply answering your question - there is no way to do it as you've described.
You can use iCloud.
Go to your app manager on Itunes Connect to generate a iCloud Key.
So, all data will be stored on icloud.
You can use too a uuid as Key for your webservice. So, if the use delete app and when he reinstall, you cad download all data with key identifier.
For example:
uuid = [[UIDevice currentDevice] uniqueGlobalDeviceIdentifier];
With Class for UUID
Important: Use the global mode because it allows to use the uuid between applications.
my dropbox-based Sync API solution:
- (IBAction)onTouchDropboxBackup:(id)sender {
DBAccount *account = [[DBAccountManager sharedManager] linkedAccount];
if (account) {
if (![sharedDelegate filesystem]) {
DBFilesystem *filesystem = [[DBFilesystem alloc] initWithAccount:account];
[DBFilesystem setSharedFilesystem:filesystem];
[sharedDelegate setFilesystem:filesystem];
[filesystem release];
}
DBPath *destination = [[DBPath root] childPath:kDataDBFileName];
DBError *error = nil;
//check presense
DBFile *file = [[DBFilesystem sharedFilesystem] openFile:destination
error:&error];
if (error){//not present
[[DBFilesystem sharedFilesystem] createFile:destination
error:&error];
file = [[DBFilesystem sharedFilesystem] openFile:destination
error:&error];
}
if (!error) {
[file writeContentsOfFile:[DOCUMENTS_DIR stringByAppendingPathComponent: kDataDBFileName]
shouldSteal:NO
error:&error];
[file update:&error];
[file close];
}
}else
[[DBAccountManager sharedManager] linkFromController:self];
}

What are the methods access sqlite db directly from bundle path in iphone sdk?

Is it ok to access sqlite db directly from bundle path OR Copy sqlite db from bundle to documentary path and then access sqlite db?
Which is efficient method? Can anyone please suggest me on this?
You can not change the files that are in bundle. If you need to change in the database you need to copy it in Documents directory. but if the database is not being changed you may keep it in bundle. But it is convention that people create copy of database in Documents directory.
Change in database = manipulate records of database.
It would be better for you to copy the DB to the Library or document Directory, and make all the process from the locally saved database in document or library folder.
I prefer to keep it to library folder such that user can not open and delete it , just for safety.
If u access the DB from the Main bundle you can have a problem, further if you upgrade the app version and want to make changes to your DB.
So, better option is to keep the DB to Document or library folder and access it from there.
Hope it makes some sense.
If you want to access or read the DB data directly from the documents directory,
You have to copy the DB to documents directory programmatically and then you can use the below code to access the DB (Select,Update,Delete operations).
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* foofile = [documentsPath stringByAppendingPathComponent:#"XYZ.sqlite"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:foofile];
if(fileExists)
{
if (foofile)
{
myText = [[NSString alloc] initWithContentsOfFile:foofile];
if (myText)
{
[self start];
}
else{;}
}
}
else
{
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"XYZ"
ofType:#"sqlite"];
if (filePath)
{
myText = [[NSString alloc] initWithContentsOfFile:filePath];
if (myText)
{
[self start];
}
else
{;}
}
}

iPhone sqlite3 locked, can only read, not write

So I have been working on this project for a short while now. I have no problems with reading data from the DB, and formatting it into UITableViews and what not. But now I am wanting also to write to the DB as well. The problem is I keep getting a "Database is Locked" error from sqlite. After messing around with the original version I had the face-palm moment by realizing my database was in the bundle and therefore not writable. So I relocated the DB to the Apps Documents folder, which is writeable. But now I still get the same "Database is Locked" sql error. I only open and close the DB when necessary. And as far as I can tell, I don't leave it open anywhere. Below is the code where I am wanting to do updates. Any thoughts?
- (BOOL) loanBookTo:(NSString *)newborrower{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"books.sqlite"];
if([[NSFileManager defaultManager] fileExistsAtPath:path]){
NSLog(#"File Exists at: %#", path);
}
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {
NSString *mySQL = #"UPDATE BOOKS SET LOANED = 1, BORROWER = \"<BORROWER>\" where ISBN = \"<ISBN>\"";
mySQL = [mySQL stringByReplacingOccurrencesOfString:#"<ISBN>" withString:self.isbn];
mySQL = [mySQL stringByReplacingOccurrencesOfString:#"<BORROWER>" withString:newborrower];
const char *sql = [mySQL UTF8String];
char* errmsg;
sqlite3_exec(database, sql, NULL, NULL, &errmsg);
// Q. Database is locked. Why?
// A. Because it is in the Bundle and is ReadOnly.
// Need to write a copy to the Doc folder.
// Database is Locked error gets spit out here.
printf(errmsg);
sqlite3_close(database);
}
return NO;
}
Open the database once at the start of your app, then close it in applicationWillTerminate of the AppDelegate.
After every exec you will want to do a reset to clear the connection state.
Take a look at the SQLiteBooks sample app, it is coded this way.
How do you move the DB to the documents folder from the bundle? You need to check that it is there, and if not copy it. I get the feeling that either you have copied it some other way, but retained a read-only attribute, or more likely, you are still referencing the original in the bundle.
For details see
Where would you place your SQLite database file in an iPhone app?
or as joshperry says, the SQLiteBooks sample has all the code you need.
How are you getting to loanBookTo? If the database is open and then you call loanBookTo, it may not throw an error of the open, however the database is holding the state from where you came.
Also, at times, the database retains the locked state upon closing and exiting the application, so you could be 'inheriting' a locked state from your previous failures. Deleting the app from the simulator should give you a clean copy.

Sqlite3 gives "no such table" error on iPhone

I created a sqlite3 database, created tables and insert some data. I can retrieve using select query by using terminal application.
But when i add this database to my iPhone application resources and try to access data programatically I get error as "no such table: table name"
Why does this happen?
sqlite3_open() creates an empty database for you if the database path does not exist. So, it is possible that the path you gave it does not lead you to the intended file. With an empty database, you get "no such table" a lot.
The DB file is probably not reachable by the iPhone. Try creating the DB from the iPhone app itself.
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES
);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [
documentsDirectory stringByAppendingPathComponent:#"yourdbname.sql"
];
// Open the database. The database was prepared outside the application.
if (sqlite3_open([path UTF8String], &db_handle) != SQLITE_OK) {
// Even though the open failed,
// call close to properly clean up resources.
sqlite3_close(db_handle);
NSAssert1(0,
#"Failed to open database with message '%s'.",
sqlite3_errmsg(db_handle)
);
}
And the perform your query again. Also, it helps if you check for potential errors on every step of your DB access code.
I had the same error with sqlite3X C++ wrapper.
I use this library in my IE-plugin.
The problem was in unavailability .sqlite base.
Current directory for IE(not plugin) is "C:\Documents and Settings\UserName\desktop\".
When I put my base in this location - problem was solved.