I want to initialize my app with a small sqlite3 DB. I tried to put it in the Documents directory, but sometimes it copies it with zero size and sometimes it doesnot copy it at at all.
How sholud I initialize my app with a DB full of info?
Thankyou
How do you copy it with your application?
If you ship your application with DB inside app bundle (as a resource) you should copy it to the documents folder from resources if it is absent and work with it there:
NSFileManager *fileManager = [[NSFileManager defaultManager] autorelease];
BOOL exists = [fileManager fileExistsAtPath:databasePath];
if (exists) {
return;
}
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
Thank you Vladimir,
This was helpful. I made a few changes and here is the final result that works great:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *databasePath = #"personalLMS.s3db";
NSFileManager *fileManager = [[NSFileManager defaultManager] autorelease];
NSString * databasePathFromApp = [[NSBundle mainBundle] pathForResource:#"personalLMS" ofType:#"s3db"];
[fileManager copyItemAtPath:databasePathFromApp toPath:[documentsDirectory stringByAppendingPathComponent:databasePath] error:nil];
Related
i have one subfolder in Resources with name SketchImages which contains 300 PNG images, what i need to do is on the startup of my app copy this folder in document folder of iphone sdk, i am trying the following code with no luck
BOOL success;
NSFileManager *fileManager = [[NSFileManager defaultManager] init];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *documentDBFolderPath = [documentsDirectory
stringByAppendingPathComponent:#"SketchImages"];
success = [fileManager fileExistsAtPath:documentDBFolderPath];
if (success)
{
return;
}else
{
NSString *resourceDBFolderPath = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:#"DB"];
//[fileManager createDirectoryAtPath: documentDBFolderPath attributes:nil];
[fileManager copyItemAtPath:resourceDBFolderPath toPath:documentDBFolderPath
error:&error];
}
any help will be highly appriciated
You use the wrong subfolder name:
NSString *resourceDBFolderPath = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:#"SketchImages"];
I'm learning Objective-C, so please, be nice. :-)
While learning how to connect Objective-C and a SQLite db, I found some authors suggesting to use this method (or a very similar one) before starting querying the db:
-(void) checkAndCreateDatabase{
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
success = [fileManager fileExistsAtPath:databasePath];
if(success) return;
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
[fileManager release];
}
Which is the main advantage of using this code over using NSString *dbPath = [[NSBundle mainBundle] pathForResource:#"myDb" ofType:#"sqlite"] ?
In iOS you can not write to the app bundle so the database is usually copied to the apps sandbox area.
The following code is fine to get the path to your database in the app bundle:
NSString *dbPath = [[NSBundle mainBundle] pathForResource:#"myDb" ofType:#"sqlite"];
The document directory path can be found with this code:
NSArray *documentDirList = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [documentDirList objectAtIndex:0];
There are several other directories you can search for, lookup the enumeration: NSSearchPathDirectory.
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];
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];
}
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.");
}