Unable to create folder inside document directory - ios

I developed iPhone app in which i got stuck at one point,
What i want to do is,
I want to copy my Database from bundle to folder inside document directory
When i try to create folder inside DocDir it doesn't getting created and it shows error,
Failed to create MyDB.sql file with message 'The operation couldn’t be completed. (Cocoa error 4.)
Here is my code snippet,
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [[paths objectAtIndex:0] stringByAppendingString:#"/NewFolder/"];
NSString *dbPath = [documentsDir stringByAppendingPathComponent:#"MyDB.sql"];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success) {
NSString *defaultDBPath = [[NSBundle mainBundle] pathForResource:#"MyDB" ofType:#"sql"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
Where i am doing mistake? please help
Thanks in advance.

Try to create directory by following code, may you get help..
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"/YourFolder"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])//Check
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]; //Will Create folder

Related

iOS: Is this the proper way to create a directory in Application Support to store my SQL file?

I have a sqlite file that I am trying to store in Application Support Folder. I am using the following code to create the directory.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *applicationSupportDirectory = [paths firstObject];
NSError *err;
NSString *dataPath = [applicationSupportDirectory stringByAppendingPathComponent:#"/Email"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&err]; //Create folder
NSString *dataBasePath = [applicationSupportDirectory stringByAppendingString:#"/Email/Email.sqlite"];
This is the printed result when I NSLog dataBasePath
/var/mobile/Containers/Data/Application/8A40E5A9-EEE6-46EF-B71F-36C9A00D5996/Library/Application
Support/Email/Email.sqlite
Is this correct way of creating the directory to store my sql file in Application Support? I have to use Application Support so the user can't mess with it (I use file share so document directory is out of the question) and the OS shouldn't be able to mess with it either. I just need to be sure
It's close but not quite right. Don't put the / before Email. You want to pass YES to withIntermediateDirectories. And the final path should use dataPath and stringByAppendingPathComponent.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *applicationSupportDirectory = [paths firstObject];
NSString *dataPath = [applicationSupportDirectory stringByAppendingPathComponent:#"Email"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath]) {
NSError *err;
if (![[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:YES attributes:nil error:&err]) { //Create folder
NSLog(#"Unable to create folder at %#: %#", dataPath, err);
}
}
NSString *dataBasePath = [dataPath stringByAppendingPathComponent:#"Email.sqlite"];

Keep on changing the address of database in IOS

Everytime I run my app, database address is changed so my update or retrieval is not successfully working.
Any one can help me why this is happening with me... here my code to copy my database to the directory.
(BOOL)createDB
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath = [self getDBPath];
dataPath=dbPath;
databasePath = dbPath;
NSLog(#"Path is: %#",dbPath);
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"babynames.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
return success;
}
Here is getDBPathCode
- (NSString *)getDBPath
{`NSSearchPathForDirectoriesInDomains`
//Search for standard documents using NSSearchPathForDirectoriesInDomains
//First Param = Searching the documents directory
//Second Param = Searching the Users directory and not the System
//Expand any tildes and identify home directories.
'NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
//NSLog(#"dbpath : %#",documentsDir);
return [documentsDir stringByAppendingPathComponent:#"babynames.sqlite"];'
}

NSFileManager moving a file shows error

I am trying to create two log files and replace content in the second file with the content in the first file.
My code for creating log in AppDelegate
NSArray *paths3 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory3 = [paths3 objectAtIndex:0];
logPath3 = [documentsDirectory3 stringByAppendingPathComponent:#"console4.log"];
if(![[NSFileManager defaultManager] fileExistsAtPath:logPath3])
[[NSFileManager defaultManager] createFileAtPath:logPath3 contents:[NSData data] attributes:nil];
NSLog(#"path %#",logPath3);
freopen([logPath3 cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
NSArray *paths2 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory2 = [paths2 objectAtIndex:0];
logPath2 = [documentsDirectory2 stringByAppendingPathComponent:#"console3.log"];
if(![[NSFileManager defaultManager] fileExistsAtPath:logPath2])
[[NSFileManager defaultManager] createFileAtPath:logPath2 contents:[NSData data] attributes:nil];
NSLog(#"path %#",logPath2);
freopen([logPath2 cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
_isFileOneCreated =YES;
code to move content
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
NSError * err;
if ([filemgr moveItemAtPath:
logPath2 toPath:
logPath3 error: &err])
NSLog (#"Day 3 Move successful");
else
NSLog (#"Day 3 Move failed %#",[err localizedDescription]);
But i get an error 516.
(Cocoa error 516.)" UserInfo=0x16dba220 {NSSourceFilePathErrorKey=/var/mobile/Containers/Data/Application/274E9843-2C8E-45F3-BD41-EA392F50C7AC/Documents/console3.log, NSUserStringVariant=(
Move
), NSFilePath=/var/mobile/Containers/Data/Application/274E9843-2C8E-45F3-BD41-EA392F50C7AC/Documents/console3.log, NSDestinationFilePath=/var/mobile/Containers/Data/Application/274E9843-2C8E-45F3-BD41-EA392F50C7AC/Documents/console4.log, NSUnderlyingError=0x16da63f0 "The operation couldn’t be completed. File exists"}
Help me solve my issue
moveItemAtPath does not allow you to overwrite the file with same name. See this Question Thread.
All you need to do is delete the file at target location before you overwrite with new one. Use the below code. This will do the trick but i advice you to take precaution to have the backup of your file just in case move doesn't work for some unknown reason.
NSFileManager *filemgr = [NSFileManager defaultManager];
NSError * err;
[filemgr removeItemAtPath:logPath3 error:&err];
if ([filemgr moveItemAtPath:logPath3 toPath:logPath2 error: &err])
NSLog (#"Day 3 Move successful");
else
NSLog (#"Day 3 Move failed %#",[err localizedDescription]);

Better way to save sqlite database file(.db) in ios application

What is better way to copy sqlite database file(.db) in ios application means that in NSBundle or in Document folder.
You can try this
- (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:#"DB.sqlite"];
success = [fileManager fileExistsAtPath:writableDBPath];
if (success) return;
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"KURANDB2.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if (!success) {
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}

add Separate .sqlite file to ios project

I have created a myDB.sqlite database from SQLite Manager firefox addon. I want to add this myDB.sqlite file to my project. Then I can write functions to get data from tables.
I tried to add the myDB.sqlite file to project folder & create a filepath like this. But I think this filepath is wrong.
-(NSString *) filePath{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"document.sqlite"];
return path;
}
Does it correct to add myDB.sqlite file to the project folder? or where should I save this myDB.sqlite file & what is the filepath I should use?
add your myDB.sqlite file in your project. by right click your project name=> add files to ""projectName", then add it.
to get your file path you can add this in your appDelegate
- (void) copyDatabaseIfNeeded {
//Using NSFileManager we can perform many file system operations.
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *dbPath = [self getDBPath];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success) {
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"database.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
- (NSString *) getDBPath
{
//Search for standard documents using NSSearchPathForDirectoriesInDomains
//First Param = Searching the documents directory
//Second Param = Searching the Users directory and not the System
//Expand any tildes and identify home directories.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
//NSLog(#"dbpath : %#",documentsDir);
return [documentsDir stringByAppendingPathComponent:#"myDB.sqlite"];
}
in your did finish with launching method call [self copyDatabaseIfNeeded];
I assume you have successfully copied sqlite db into project's folder. So you have sqlite Database in your app's bundle now.
So you need to copy database from app's bundle to document directory of device/simulator using following code. Write these in AppDelegate.m
- (void) copyDatabaseIfNeeded
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSString *folderPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0];
// First, test for existence.
if (![fileManager fileExistsAtPath:folderPath])
[fileManager createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:&error]; //Create folder
NSString *dbPath = [folderPath stringByAppendingPathComponent:#"document.sqlite"];
BOOL success = [fileManager fileExistsAtPath:dbPath];
if(!success)
{
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"document.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error];
if (!success)
NSAssert1(0, #"document.sqlite : Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
/** Database copy is not exist **/
[self copyDatabaseIfNeeded];
// Override point for customization after application launch.
return YES;
}
-(void)addSqlFileIfNotExists {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentDirectory stringByAppendingPathComponent:#"document.sqlite"];
BOOL exits = [fileManager fileExistsAtPath:writableDBPath];
if(exits) return;
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"document.sqlite"];
BOOL exit = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
if(!exit)
NSLog(#"%#",[error localizedDescription]);
}

Resources