Where does iPhone simulator put data files? - iphone

If I compile my iPhone App with a database that has been built into the bundle what path do I have to use to find the file so that I can open it, as in:
FMDatabase* db = [FMDatabase databaseWithPath:#"/???/database.sqlite"];

Inside your - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
set the following code:
databaseName=#"yourfileName.sqlite";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
[self checkAndCreateDatabase];
-(void) checkAndCreateDatabase
{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:databasePath];
if(success) return;
else
printf("NO File found");
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}

You can use like this regardless of simulator or device. Please dont forget to add db file to your project folder and add to your bundle.
#define DATABASE #"databasefile.sqlite"
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [[NSString alloc] initWithString:[documentsDir stringByAppendingPathComponent:DATABASE]];

Related

sqlite3_open - Can't open database

I have the following statement in my code:
NSString *docsDir;
NSArray *dirPaths;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
databasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent:#"Notebook.sqlite"]];
NSFileManager *fileMgr = [NSFileManager defaultManager];
const char *dbpath = [databasePath UTF8String];
NSLog(#"open sqlite at %s",dbpath);
if (sqlite3_open(dbpath, &noteDB)==SQLITE_OK)
the output of NSLog is
/Users/GinLin/Library/Application Support/iPhone Simulator/7.0/Applications/CE1BAB1C-3DEC-4A1D-A083-537B0B51C99D/Library/Documentation/Notebook.sqlite
but it doesn't seem to be opening my database.
And I cannot find the folder "Documentation" under "/CE1BAB1C-3DEC-4A1D-A083-537B0B51C99D/Library/".
Could anyone help?
I believe you meant to use NSDocumentDirectory not NSDocumentationDirectory, e.g.:
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
First you must check if the DB path contains de file, else, copy the DB
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString* resourcePath=[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"database.db"];
//Destination path
NSString *dbPath = [[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"] stringByAppendingPathComponent:#"database.db"];
//Find file
BOOL success = [fileMgr fileExistsAtPath:dbPath];
if(success==YES){
NSLog(#"File found");
}else{
NSError* error;
if(![fileMgr copyItemAtPath:resourcePath toPath:dbPath error:&error]){
NSLog(#"Can't copy");
}else{
NSLog(#"That's all :D");
}
}

IPhone ios 5, recreate database on each simulator run?

How can i replace the database (with the one i am working on) in my app on each simulator run? (Still adding data and want to check that it looks good)
I tried this but it doesn't seem to be working, still using the old database:
- (void)viewDidLoad
{
dbname = #"animaldatabase.sql";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
dbpath = [documentsDir stringByAppendingPathComponent:dbname];
[self checkAndCreateDatabase];
[self readAnimalsFromDatabase];
[super viewDidLoad];
// Do any additional setup after loading the view.
mylabel.text = [NSString stringWithFormat:#"%d", [animals count]];
}
- (void) checkAndCreateDatabase{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:dbpath];
if (success) {
//return;
[fileManager removeItemAtPath:dbpath error:nil];
}
NSString *dbPathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:dbname];
[fileManager copyItemAtPath:dbPathFromApp toPath:dbpath error:nil];
}
Also where is the location for the iphone database? When my app copies the database into the iphone, where does it end up?
UPDATE
Added the loading code as well.
Senthilkumar:
I fail to see how this should solve the problem? Doesn't this just skip the copying or my database if it already exists?
What i want is to delete the database in my iphone app. Import the new database and then run it.
use the following code instead of that.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
databaseName=#"yourfileName.sqlite";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
[self checkAndCreateDatabase];
}
-(void) checkAndCreateDatabase {
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:databasePath];
if(success) return;
else
printf("NO File found");
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}
To help debug file manager operations, it helps to try and use the error parameter, like so:
NSError* error;
[fileManager copyItemAtPath:dbPathFromApp toPath:dbpath error: &error];
if (error != nil) {
NSLog(#"copyItemAtPath generated error=%#", [error localizedDescription]);
}
If you do this, the error message will get written to your debugger console / standard output window.

[NSBundle mainBundle]pathForResource returns nil

I'm trying to connect my app to SQLite database but I get messages that tell me that the database is created but there are no tables.
I debugged the program and discovered that
[[NSBundle mainBundle] pathForResource] always returns nil
NSString* file = [[NSBundle mainBundle]pathForResource:_databaseName ofType:_databaseType];
Why is this happening?
Please help me!
First : make sure your database is in the app bundle.
Then you need to implement methods to copy the path to the documentary Directory .as these
-(NSString *) getDBPath:(NSString*)databaseName {
// search for the existed paths
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
return [documentsDir stringByAppendingPathComponent:databaseName];
}
- (void) InstantiateYourDatabase:(NSString *)DatabaseName {
//Using NSFileManager we can perform many file system operations.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dpname=DatabaseName;
_dbPath = [self getDBPath:dpname];
BOOL success = [fileManager fileExistsAtPath:_dbPath];
NSLog(#"success == %i",success);
if( !success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:DatabaseName];
success = [fileManager copyItemAtPath:defaultDBPath toPath:_dbPath error:&error];
}
}
Tell me if it helps!
try below code for find database path
NSString *databaseName = #"your_db_name.sql";
NSString *databasePath;
// 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];
NSLog(#"Database Path is: %#",databasePath);
You want More Detail about Sqllite Database Connectivity in iOS try this tutorial
Welcome!
If you created a sqlite db file and drag it to your project in xcode3, it's in application document folder while its running.
NSString *databaseName = #"cartoon.db";
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [documentPaths objectAtIndex:0];
NSString *databasePath = [documentDir stringByAppendingPathComponent:databaseName];
Whenever you are using the database you have to use the Documents Directory

how do we open an already existing database fmdb and where to include it?

I am using fmdb but i am not knowing where to add the db file.
I found this old answer that i think it doesn't fit for xcode 4.2 (since we dont have 'Resources' folder anymore).
I created a database in 'Lita', added the extension .sqlite and added the db file as follows :
then tried to use the following
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:#"db.sqlite"];
FMDatabase *database = [FMDatabase databaseWithPath:path];
[database open];
FMResultSet *results = [database executeQuery:#"select * from tbl"];
printf("hi");
while([results next]) {
printf("hi2");
NSString *name = [results stringForColumn:#"clm1"];
NSString *text = [results stringForColumn:#"clm2"];
NSLog(#"test: %# - %#",name, text);
}
printf("done");
i am getting the 'hi' 'done' but never 'hi2'...
anyone can help?
You want to add the (compiled) database to the project as a resource, and then copy it into the documents folder of the app on first start-up.
Here is an example method that does the work, call it from the applicationDidFinishLaunching and use the resultant FMDatabase * for all you queries.
- (FMDatabase *)openDatabase
{
NSFileManager *fm = [NSFileManager defaultManager];
NSString *documents_dir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *db_path = [documents_dir stringByAppendingPathComponent:[NSString stringWithFormat:#"database.s3db"]];
NSString *template_path = [[NSBundle mainBundle] pathForResource:#"template_db" ofType:#"s3db"];
if (![fm fileExistsAtPath:db_path])
[fm copyItemAtPath:template_path toPath:db_path error:nil];
FMDatabase *db = [FMDatabase databaseWithPath:db_path];
if (![db open])
NSLog(#"Failed to open database!");
return db;
}
I am working with the same issues right now. But to answer your question: the documents folder is the folder that is to be used in the device.
Put the database in the the supporting files folder.
Here is what works for me:
//hide status bar for full screen view
[[UIApplication sharedApplication]setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
//set reference to database here
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [documentPaths objectAtIndex:0];
self.databasePath = [documentDir stringByAppendingPathComponent:#"RPRA.sqlite"];
[self createAndCheckDatabase];
// Override point for customization after application launch.
return YES;
}
//method used to create database and check if it exists
-(void) createAndCheckDatabase
{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:self.databasePath];
if(success) return;
//else move database into documents folder
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:#"RPRA.db"];
[fileManager copyItemAtPath:databasePathFromApp toPath:self.databasePath error:nil];
}
- (void)ensureDBFile
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dbFilePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"retails.sqlite"]];
NSLog(#"Database Filepath Delgate = %#", dbFilePath);
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL dbFileExists = [fileManager fileExistsAtPath:dbFilePath];
if(!dbFileExists){
//Copy the db file if it didn't exist
NSString *bundledDbPath = [[NSBundle mainBundle] pathForResource:#"retails" ofType:#"sqlite"];
if (bundledDbPath != nil) {
BOOL copiedDbFile = [fileManager copyItemAtPath:bundledDbPath toPath:dbFilePath error:nil];
if (!copiedDbFile) {
NSLog(#"Error: Couldn't copy the db file from the bundle");
}
}
else {
NSLog(#"Error: Couldn't find the db file in the bundle");
}
}
self.db = [FMDatabase databaseWithPath:dbFilePath];
[self.db setShouldCacheStatements:NO];
[self.db open];
if([self.db hadError]) {
NSLog(#"Database Error %d: %#", [self.db lastErrorCode], [self.db lastErrorMessage]);
}
}

Sharing multiple files on App Via iTunes File Sharing (Code shows 1 file)

I'm trying to file share multiple files with iTunes file share.
Here is the current code.
Delegate.h
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// file sharing trying
{
NSString *fileName = #"Test.mp3";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *documentDBFolderPath = [documentsDirectory stringByAppendingPathComponent:fileName];
if (![fileManager fileExistsAtPath:documentDBFolderPath])
{
NSString *resourceDBFolderPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName];
[fileManager copyItemAtPath:resourceDBFolderPath toPath:documentDBFolderPath error:&error];
}
}
[self.window makeKeyAndVisible];
return YES;
}
At the moment only 1 file gets shared.
Thanks
I assume you want to add a bunch of files in an NSArray? then loop through it like this:
NSArray *names = [NSArray arrayWithObjects: #"foo", #"bar", nil];
for (NSString *fileName in names)
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *documentDBFolderPath = [documentsDirectory stringByAppendingPathComponent:fileName];
if (![fileManager fileExistsAtPath:documentDBFolderPath])
{
NSString *resourceDBFolderPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:fileName];
[fileManager copyItemAtPath:resourceDBFolderPath toPath:documentDBFolderPath error:&error];
}
}