Problem in copying a folder from resource to documents directory [duplicate] - iphone

I'm having the hardest time getting this to work. I'm trying to copy a folder from my bundle to the documents directory.
the folder I'm trying to find is here:
...app/Resources/12/(a bunch of jpgs)
NSString *myPath = [[[NSBundle mainBundle] resourcePath]stringByAppendingPathComponent:#"12"];
NSLog(#"%#",myPath);/// returns "..../MyApp.app/12"
NSArray *arrayOf12s = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:myPath error:nil];
NSLog(#"%#",arrayOf12s); ////always returns NULL

How about using the NSError argument in -contentsOfDirectoryAtPath:error: call?
NSString *myPath = [[[NSBundle mainBundle] resourcePath]stringByAppendingPathComponent:#"12"];
NSLog(#"%#",myPath);/// returns "..../MyApp/12"
NSError *error = nil;
NSArray *arrayOf12s = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:resourceDBFolderPath error:&error];
if (error)
NSLog(#"Error: %#", [error localizedDescription]);
NSLog(#"%#",arrayOf12s); ////always returns NULL
It might shine some light on the cause...

Related

How to copy a file from URL to document folder?

I need to copy a text file from an URL and place / overwrite it in my app's document folder and then read it back to a data variable.
I have the following code:
NSData *data;
//get docsDir
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir=[paths objectAtIndex:0];
//get path to text.txt
NSString *filePath=[docsDir stringByAppendingPathComponent:#"text.txt"];
//copy file
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
if([fileManager fileExistsAtPath:filePath]==YES){
[fileManager removeItemAtPath:filePath error:&error];
}
NSString *urlText = #"http://www.abc.com/text.txt";
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSFileManager *fileManager=[NSFileManager defaultManager];
[fileManager copyItemAtPath:urlText toPath:filePath error:NULL];
}
//Load from file
NSString *myString=[[NSString alloc] initWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
//convert string to data
data=[myString dataUsingEncoding:NSUTF8StringEncoding];
It builds and complies in good way but I cannot create the text.txt file in my document folder and then pass anything to my data variable.
I'm a newbie to both IOS and Xcode, any clues will be highly appreciated. Thanks!!
NSFileManager can only handle local paths. It won't do anything useful if you give it a URL.
copyItemAtPath:toPath:error: takes an error parameter. Use it, like this:
NSError *error;
if (![fileManager copyItemAtPath:urlText toPath:filePath error:&error]) {
NSLog(#"Error %#", error);
}
You would then get this error:
Error Error Domain=NSCocoaErrorDomain Code=260 "The operation couldn’t be
completed. (Cocoa error 260.)" UserInfo=0x9a83c00 {NSFilePath=http://www.abc.com/text.txt,
NSUnderlyingError=0x9a83b80 "The operation couldn’t be completed.
No such file or directory"}
It can't read the file at http://www.abc.com/text.txt, because it is not a valid path.
as Sunny Shah stated without explanation you have to fetch the object at the URL first:
NSString *urlText = #"http://www.abc.com/text.txt";
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSURL *url = [NSURL URLWithString:urlText];
NSError *error;
NSData *data = [[NSData alloc] initWithContentsOfURL:url options:0 error:&error];
if (!data) { // check if download has failed
NSLog(#"Error fetching file %#", error);
}
else {
// successful download
if (![data writeToFile:filePath options:NSDataWritingAtomic error:&error]) { // check if writing failed
NSLog(#"Error writing file %#", error);
}
else {
NSLog(#"File saved.");
}
}
}
Always check for errors!
You should get the data from the URL and use WriteToFile
NSData *urlData = [NSData dataWithContentsOfURL: [NSURL URLWithString:urlText]];
[urlData writeToFile:filePath atomically:YES];

How to read & write to an NSArray to plist?

I'm having several issues based around reading and writing an NSArray to and from a plist.
I have created a plist file in the 'Supporting Files' folder which I want to use to initialise the app data with upon the first load.
Here is what my plist looks like:
I then use this code to try load the plist into the app:
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
filePath = [documentsDirectory stringByAppendingPathComponent:kDataFile];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:filePath])
{
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"Data" ofType:#"plist"];
[fileManager copyItemAtPath:bundle toPath:filePath error:&error];
}
I then try to load the data from the plist file like so, however nothing seems to be displayed.
NSMutableDictionary *savedData = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
NSMutableArray *myNSArray = [[savedData objectForKey:#"KEY_Level_1"] mutableCopy];
savedData = nil;
Sorry if this is a simple task, however I've been looking at lots of tutorials and trying to work out how to do this with no luck. I'm getting really frustrated now - I would have thought it should be a simple thing to do.
NOTE: My NSArray will contain a whole bunch of NSDictionaries.
You need to check the return value of copyItemAtPath:toPath:error: and at least log the error if the method returns false:
if (![fileManager copyItemAtPath:bundle toPath:filePath error:&error]) {
NSLog(#"error: copyItemAtPath:%# toPath:%# error:%#", bundle, filePath, error);
return;
}
-[NSDictionary initWithContentsOfFile:] has no way to report errors, so if it's failing, you cannot easily figure out why. Try reading the file into an NSData and using -[NSPropertyListSerialization propertyListWithData:options:format:error:] to parse it:
NSData *data = [NSData dataWithContentsOfFile:filePath options:0 error:&error];
if (!data) {
NSLog(#"error: could not read %#: %#", filePath, error);
return;
}
NSMutableDictionary *savedData = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListMutableContainers format:NULL error:&error];
if (!savedData) {
NSLog(#"error: could not parse %#: %#", filePath, error);
return;
}
NSMutableArray *myNSArray = [savedData objectForKey:#"KEY_Level_1"];
savedData = nil;
if (!myNSArray) {
NSLog(#"error: %#: object for KEY_Level_1 missing", filePath);
return;
}
If you do this, you'll be able to more easily see why your data is not being loaded.
UPDATE
On further inspection, it looks like the top-level dictionary in your plist contains the key "Root". The value for "Root" is a dictionary containing the key "KEY_Level_1". So you need to do this:
NSMutableArray *myNSArray = [[savedData objectForKey:#"Root"] objectForKey:#"KEY_Level_1"];

What's wrong with my copy here?

I'm trying to copy a file from my application bundle to my app's documents directory. I'm getting an error, "Cocoa Error 262". What am I doing wrong? Here's my code:
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"CoreData.sqlite"];
NSURL *initialURL = [NSURL URLWithString:[[NSBundle mainBundle] pathForResource:#"CoreData" ofType:#"sqlite"]];
NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:[initialURL absoluteString]]) {
NSLog(#"Original does not exist. \nPath: %#", [initialURL absoluteString]);
}
if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL absoluteString]]) {
NSLog(#"Destination file does not exist. \nPath: %#", [storeURL absoluteString]);
[[NSFileManager defaultManager] copyItemAtURL:initialURL toURL:storeURL error:&error];
NSLog(#"Error: %#", [error description]);
}
The problem is you're initializing a URL with a plain old file path.
NSURL *initialURL =
[NSURL URLWithString:[[NSBundle mainBundle] pathForResource:#"CoreData"
ofType:#"sqlite"]];
Use [NSURL fileURLWithPath:] instead.
The error you are getting is
NSFileReadUnsupportedSchemeError
Read error because the specified URL scheme is unsupported
which I believe would mean one of your paths is not forming correctly. perhaps write these paths to the log and see if they are coming out as you expect them to.
I've solved the problem, although to be honest, I'm not sure what it was. I have to go over the working code again, but here it is:
NSError *error = nil;
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.%#", #"CoreData", #"sqlite"]];
//if file does not exist in document directory, gets original from mainbundle and copies it to documents.
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
NSString *defaultFilePath = [[NSBundle mainBundle] pathForResource:#"CoreData" ofType:#"sqlite"];
[[NSFileManager defaultManager] copyItemAtPath:defaultFilePath toPath:filePath error:&error];
if (error != nil) {
NSLog(#"Error: %#", error);
}
}
Edit:
I suspect that the path to the application directory was incorrect, given that the body of the generated applicationDocumentsDirectory looks different than the method used for the value of the documentsDorectory variable shown above.
Error 262 is defined in FoundationErrors.h to be NSFileReadUnsupportedSchemeError.
I'd suggest that you use NSLog() to write out the literal values of the two URLs that you're using and make sure that they are file:// URLs and that they look complete.

NSFileManager createDirectoryAtPath EXC_BAD_ACCESS

I have been working at this one for quite some time now but can't seem to resolve it. I have a core data application that also supports document sharing, therefore I'm trying to create a directory in the library folder for the sqlite db.
- (NSURL *)applicationPrivateDocumentsDirectory {
NSString *libraryDirectory = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
NSString *privateDocs = [libraryDirectory stringByAppendingPathComponent:#"PrivateDocuments"];
NSFileManager *fileMgr = [[NSFileManager alloc] init];
if (![fileMgr fileExistsAtPath:privateDocs]) {
NSLog(#"Does not exist");
NSError *error;
[fileMgr createDirectoryAtPath:privateDocs withIntermediateDirectories:YES attributes:nil error:&error];
NSLog(#"%#", [error description]);
}
NSURL *retURL = [NSURL fileURLWithPath:privateDocs];
return retURL;
}
The debug console outputs "Does not exist" followed by "EXC_BAD_ACCESS"
Any help is greatly appreciated.
Try to add this:
NSError *error = nil;

iphone copying folder from bundle to documents

I'm having the hardest time getting this to work. I'm trying to copy a folder from my bundle to the documents directory.
the folder I'm trying to find is here:
...app/Resources/12/(a bunch of jpgs)
NSString *myPath = [[[NSBundle mainBundle] resourcePath]stringByAppendingPathComponent:#"12"];
NSLog(#"%#",myPath);/// returns "..../MyApp.app/12"
NSArray *arrayOf12s = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:myPath error:nil];
NSLog(#"%#",arrayOf12s); ////always returns NULL
How about using the NSError argument in -contentsOfDirectoryAtPath:error: call?
NSString *myPath = [[[NSBundle mainBundle] resourcePath]stringByAppendingPathComponent:#"12"];
NSLog(#"%#",myPath);/// returns "..../MyApp/12"
NSError *error = nil;
NSArray *arrayOf12s = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:resourceDBFolderPath error:&error];
if (error)
NSLog(#"Error: %#", [error localizedDescription]);
NSLog(#"%#",arrayOf12s); ////always returns NULL
It might shine some light on the cause...