I am new to iOS development, I am making changes in an application which is using Sqlite. I am to add some new fields in some tables, I browsed DB with software and added new fields in
inventory_db_src.sqlite but when I see in emulator it uses inventory_db.sqlite which is strange as there is no inventory_db.sqlite file in solution and neither code creating DB through SQL script. And If I debug code it gets inventory_db.sqlite path successfully and never executes inventory_db_src.sqlite line and put inventory_db.sqlite in emulator where my new fields are not present as I put these in inventory_db_src.sqlite. pLease help me
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dbPath = [documentsDirectory stringByAppendingPathComponent:#"inventory_db.sqlite"];
// [fileManager removeItemAtPath:dbPath error:nil];
success = [fileManager fileExistsAtPath:dbPath];
success = NO;
if (success) {
int savedVersion = [[NSUserDefaults standardUserDefaults] integerForKey:kVERSION_KEY];
if (kCURRENT_DB_VERSION != savedVersion) {
[fileManager removeItemAtPath:dbPath error:nil];
success = NO;
}
}
if (!success) {
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"inventory_db_src.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success) {
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
_INVENTORY_DB = [[FMDatabase alloc] initWithPath:dbPath];
Line 6 in your code above is showing the name as inventory_db.sqlite, so that is the file your app will be using. You need to modify that to use the new database name. Be aware, that by modifying your database, you might have unexpected results so you will need to manage what DB version your app is using and make data corrections as needed. This is one nice feature that Core Data can assist in.
According to your statement it seems that old DB is cached in to your Emulator. please reset you Emulator by
iOS Simulator -> Reset content and settings
And it should work ...
Related
In My Application I am getting data (sql Table data) from server and store it in sqlite tables.which require lot of user data so that I am try to do run app on simulator and get that database file,now I am trying to do add this database file in to my project and copied it to my sqlite table(I don't know its right or wrong).it will not copied to my sqlite database.when I add this file in Xcode this looks like
then I am using this code to copy this db
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *dbPath = [documentsDir stringByAppendingPathComponent:#"moviedbl.data"];
if([fileManager fileExistsAtPath:dbPath]==NO){
NSString *defaultDBPath = [[NSBundle mainBundle] pathForResource:#"mylocaldb" ofType: #"sqlite"];
BOOL success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if(!success){
NSAssert1(0, #"Failed to create writable database file with message '%'.", [error localizedDescription]);
}
}
then it will gives me error Source path is nil.
Please suggest what should I do.Is this right way to do it.Thanks
Install SQLite Manager firefox addon and open your sqlite file from SQLite Manager addon where you can see if your sqlite contains data or not.
For DB queries and import use FMDB library it will save your time and minimize your code as well.
I'm writing an app that requires a writable sqlite file to be in the app's documents directory. I have the following code which is called in my AppDelegate method didFinishLaunchingWithOptions method.
- (void)createEditableCopyOfDatabaseIfNeeded {
// First, test for existence.
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"photos3.sqlite"];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success)
{
NSLog(#"database exists");
return;
}
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"photos3.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success) {
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
The file name and extension are correct; and have worked with previous versions of the database. The database is located within my project, but when I run the code, I get the following message:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Failed to create writable database file with message 'The operation couldn’t be completed. (Cocoa error 260.)'.'
Googling this error code tells me that it is a "read error (no such file)." However, the file is clearly there in the project. Can anyone help me solve this problem?
Fixed by going to Project > Build Phases > Copy Bundle Resources and adding the sqlite file there. I thought it had already been added, but was mistaken.
NSFileManager *fileMgr = [[NSFileManager alloc] init];
NSError *error = nil;
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSArray *files = [fileMgr contentsOfDirectoryAtPath:cachePath error:nil];
for (NSString *path in files)
{
NSString *fullPath = [cachePath stringByAppendingPathComponent:path];
BOOL removeSuccess = [fileMgr removeItemAtPath:fullPath error:&error];
if (!removeSuccess)
{
return error;
}
}
the code above occasionally gives cocoa error 513 which is about permissions. I download files from internet placing in caches directory. Do I have to explicitly set some permissions or do something else? Why the error happens only sometimes? It never happens on 6.0/7.0, but happens sometimes on 7.1.
As I write in comment I guess the problem related to deleting some system files that not directly own by your app and should not be deleted.
for example how looks Cache folder in basic app with one UIWebView
To avoid strange errors is better to create dedicated folder inside Library/Caches and delete content inside respected to your needs
I am trying to write some image data to disk on iOS, but while it's working perfectly in the Simulator, when I try it on a real iPad it fails (returns 0).
BOOL success = [[NSFileManager defaultManager] createFileAtPath:filePath contents:imageData attributes:nil];
The path in question looks something like this: /Library/Caches/_0_0_0_0_1100_1149.jpg and I've also tried /Documents/....
Is there any way to actually get an error code or something beyond just success/fail?
The simulator does not simulate the sandboxing of the file system that is enforced on a device. You can write anywhere on the sim, but on a device writing anywhere but one of your designated directories will fail.
I'm guessing that your path is badly formed somehow. Try logging your path and the path you get from NSCachesDirectory (as shown in your second post.) They are almost certainly different.
Turns out you have to programmatically obtain the directory. The iOS file system is not sandboxed like I expected.
NSString* pathRoot = NSSearchPathForDirectoriesInDomains( NSCachesDirectory, NSUserDomainMask, YES )[0];
If you're writing image data, why not try writing via NSData's [writeToFile: options: error:] method, the "error" parameter for which can give you some really useful hints as to why your file isn't writing.
This is illogical:
if ( !( [ fileManager copyItemAtPath:resourceDBFolderPath toPath:documentDBFolderPath error:&error ]))
You are checking if the method exists, not if it succeeded!!
I have some relevant code I've used in my project, I hope it may be help you some way or another:
-(void)testMethod {
NSString *resourceDBFolderPath;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *documentDBFolderPath = [documentsDirectory stringByAppendingPathComponent:#"plans.gallery"];
BOOL success = [fileManager fileExistsAtPath:documentDBFolderPath];
if (success){
NSLog(#"Success!");
return;
}
else {
//simplified method with more common and helpful method
resourceDBFolderPath = [[NSBundle mainBundle] pathForResource:#"plans" ofType:#"gallery"];
//fixed a deprecated method
[fileManager createDirectoryAtPath:documentDBFolderPath withIntermediateDirectories:NO attributes:nil error:nil];
[fileManager copyItemAtPath:resourceDBFolderPath toPath:documentDBFolderPath
error:&error];
//check if destinationFolder exists
if ([ fileManager fileExistsAtPath:documentDBFolderPath])
{
//FIXED, another method that doesn't return a boolean. check for error instead
if (error)
{
//NSLog first error from copyitemAtPath
NSLog(#"Could not remove old files. Error:%#", [error localizedDescription]);
//remove file path and NSLog error if it exists.
[fileManager removeItemAtPath:documentDBFolderPath error:&error];
NSLog(#"Could not remove old files. Error:%#", [error localizedDescription]);
return;
}
}
}
}
I have a bunch of images stored in an images directory within my Supported Files directory in Xcode. I want to be able to show one of those images. What is the best way to obtain a path to that image? Do I have to copy them to the Documents directory first? If so, how can I do that?
EDIT: I've tried the following to copy the image from Supporting Files to the Documents folder in the app. It successfully copies, but I can't get the image to show:
-(void)findImage:(NSString *)imageName
{
// First, test for existence.
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appImagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.jpg",imageName]];
success = [fileManager fileExistsAtPath:appImagePath];
if (success)
{
return;
}
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultImagePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.jpg",imageName]];
success = [fileManager copyItemAtPath:defaultImagePath toPath:appImagePath error:&error];
if (!success)
{
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
self.imageDisplay.image = [UIImage imageNamed:appImagePath];
return;
}
This should do the trick:
[UIImage imageNamed:#"someImageName"];
EDIT:
Some additional information:
-imageNamed: will look through the entire main bundle of the application for an imagefile (preferrably an png) with the filename of "someImageName". You need not worry about its location or its extension, since it will be searched for in the mainbundle. Files that you import through the import-file-dialogue in xcode will be added to he main bundle.
This means:
If i have imported a file called myImage.png, calling [UIImage imageNamed:#"myImage"];from anywhere in my code will get me a UIImage-Object containing that image. Its amazingly simple, and maybe that startled you a bit ;)
Look it up in the docs if you like:
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIImage_Class/Reference/Reference.html