[NSBundle mainBundle]pathForResource returns nil - iphone

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

Related

Where does iPhone simulator put data files?

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

iPhone : Unable to copy from MainBundle to NSDocumentDirectory

I am trying to copy a couple of image files from my MainBundle/SampleImages folder to the application NSDocumentDirectory/Library folder, but am unable to do so. I have checked that the images are in .app/Mainbundle/SampleImages directory and I have also checked that the Library folder is being created in the NSDocumentsDirectory, but no files are copied.
I have tried two approaches, given below, but with no success.
here is the code that I am using to copy files.
First Method
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *documentLibraryFolderPath = [documentsDirectory stringByAppendingPathComponent:#"Library"];
NSString *resourceSampleImagesFolderPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"SampleImages"];
NSData *mainBundleFile = [NSData dataWithContentsOfFile:resourceSampleImagesFolderPath];
[[NSFileManager defaultManager] createFileAtPath:documentLibraryFolderPath
contents:mainBundleFile
attributes:nil];
Second Method
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *documentSampleImagesFolderPath = [documentsDirectory stringByAppendingPathComponent:#"Library"];
NSString *resourceSampleImagesFolderPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"SampleImages/"];
[fileManager createDirectoryAtPath: documentSampleImagesFolderPath attributes:nil];
if([fileManager copyItemAtPath:resourceSampleImagesFolderPath toPath:documentSampleImagesFolderPath error:&error]) {
NSLog(#"success");
}
else {
NSLog(#"Failure");
NSLog(#"%d",error);
}
I have spent a couple of hours looking for a solution, any help here would be appreciated greatly.
Thank You
Shumais Ul Haq
I got it done with the second method by changing it bit.
There is no need for creating the directory as the SDK docs say that the destination directory must not exist.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *documentDBFolderPath = [documentsDirectory stringByAppendingPathComponent:#"Library"];
NSString *resourceDBFolderPath = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:#"SampleImages"];
[fileManager copyItemAtPath:resourceDBFolderPath toPath:documentDBFolderPath error:&error];

Creating a plist file only on first runnable in the device's documents directory

I current have everything setup to read from the documents directory and write to it , but Cannot do it because the file doesnt exist yet.
How is a file created within the code?
If you already have a template version of the document in your application's bundle then you should be able to write it to the application's document directory using something similar to the following. I haven't tested this code so I've probably got a few things wrong but that's the general idea.
- (void) applicationDidFinishLaunching {
NSArray* directories = NSSearchPathsForDirectoriesInDomain(NSDocumentsDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [directories objectAtIndex: 0];
NSString* path = [documentsDirectory stringByAppendingPathComponent: #"Something.plist"];
if (![[NSFileManager sharedInstance] fileExistsAtPath: path]) {
NSString* infoTemplatePath = [[NSBundle mainBundle] pathForResource: #"Something" ofType: #"plist"];
NSDictionary* info = [NSDictionary dictionaryWithContentsOfFile: infoTemplatePath];
[info writeToFile: path];
}
}
Use NSFileManger's fileExistsAtPath: to see if the file exist. If not create it before going on to the code that requires the file.
This one works better for me:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *documentDBFolderPath = [documentsDirectory stringByAppendingPathComponent:#"*.db"];
if (![fileManager fileExistsAtPath:documentDBFolderPath])
{
NSString *resourceDBFolderPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"*.db"];
[fileManager copyItemAtPath:resourceDBFolderPath toPath:documentDBFolderPath error:&error];
}

How to get resources path?

I run my app on Simulator in XCode and it works fine but when I try to run it on the device it doesn't work.
I figured out that it doesn't open some files.
(I don't know if it gets wrong path or maybe the files aren't copied)
Before I open my files I get their path like that:
const char* Pobierz_sciezke(const char *tytul_c)
{
NSString *tytul = [NSString stringWithUTF8String: tytul_c];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *myPathDocs = [documentsDirectory stringByAppendingPathComponent:tytul];
if (![[NSFileManager defaultManager] fileExistsAtPath:myPathDocs])
{
NSString *myPathInfo = [[NSBundle mainBundle] pathForResource:#"tex_dane" ofType:#"txt"];
NSFileManager *fileManager = [NSFileManager defaultManager];
}
NSLog(#"%#",myPathDocs);
const char *sciezka;
sciezka = [myPathDocs UTF8String];
return sciezka;
}
Is this code ok?
Maybe I should add my resources in a different way? Change project settings?

PList Chicken/Egg Scenario

I want to read/write to cache.plist
If I want to read an existing premade plist file stored in the resources folder I can go:
path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathWithComponent#"cache.plist"];
NSMutableDictionary *root = ...
But then I wish to read it from the iPhone.
Can't, the Resources folder is only readable.
So I need to use:
NSDocumentDirectory, NSUserDomain,YES
So how can I have my plist file preinstalled to the Document Directory location?
Thus meaning I don't have to mess around with untidy code copying the plist file over at startup. (Unless that's the only way).
I know this isn't really what you're after, but as far as I know the only way to get the document into the Documents folder IS to actually copy it there...but only on the first startup. I'm going something similar for a sqlite database. Code is below, it works but please note it could do with a little bit of cleaning up:
// Creates a writable copy of the bundled default database in the application Documents directory.
- (void)createEditableCopyOfDatabaseIfNeeded {
// First, test for existence.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"WordsDatabase.sqlite3"];
createdDatabaseOk = [fileManager fileExistsAtPath:writableDBPath];
if (createdDatabaseOk) return;
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"WordsDatabase.sqlite3"];
createdDatabaseOk = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
}
Just call in your AppDelegate - not too messy really?
Easy. Look first to see if it's in the documents directory. If it's not, find it inside your app's Resources folder ([[NSBundle mainBundle] pathForResource...]), then copy it into the documents directory using [[NSFileManager defaultManager] copyItemAtPath:...]. Then use the fresh copy in the documents directory with impunity.
The final product
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:#"Cache.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *giveCachePath = [documentsDirectory stringByAppendingPathComponent:#"Cache.plist"];
BOOL fileExists = [fileManager fileExistsAtPath:giveCachePath];
if (fileExists) {
NSLog(#"file Exists");
}
else {
NSLog(#"Copying the file over");
fileExists = [fileManager copyItemAtPath:finalPath toPath:giveCachePath error:&error];
}
NSLog(#"Confirming Copy:");
BOOL filecopied = [fileManager fileExistsAtPath:giveCachePath];
if (filecopied) {
NSLog(#"Give Cache Plist File ready.");
}
else {
NSLog(#"Cache plist not working.");
}