I have an app that is supposed to save to a file and later on load it. Now, I have not had ANY problems what so ever on ios 4, so this is perplexing. This has happened on all my apps saving and loading.
Heres the code:
- (NSString *)pathOfFile{
NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsFolder = [paths objectAtIndex:0];
return [documentsFolder stringByAppendingFormat:#"awesome.plist"];
}
Later in in the app...
[array writeToFile:[self pathOfFile] atomically:YES];
And then when I attempt to load it...
if ([[NSFileManager defaultManager] fileExistsAtPath:[self pathOfFile]]) {
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:filepath];
achi.text = [array objectAtIndex:0];
}
My app actually just skips over the if statement (Meaning that it can't find the file I think).
Please help, and if you have different methods of saving files, I would be glad to hear to hear them.
Your - (NSString *)pathOfFile method is wrong. It should be:
- (NSString *)pathOfFile
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsFolder = [paths objectAtIndex:0];
return [documentsFolder stringByAppendingPathComponent:#"awesome.plist"];
}
In your -(NSString *)pathOfFile method, don't use stringByAppendingFormat:. When working with file paths, you should instead use stringByAppendingPathComponent:, as it will ensure that the appropriate slash characters are added (or removed, if there are too many):
return [documentsFolder stringByAppendingPathComponent:#"awesome.plist"];
The comment to my question was what solved the problem, but as I can't give him the correct answer, I'll just write paste his answer here:
Did you make sure the directory is there? Sometimes that Documents directory must be created.
Related
I have interesting thing here, I'm using xcode 4 for my project and I want to create simple .plist file to save several values which will be used for different purposes during code execution. This is the code I use to create plist:
- (NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:#"somelist.plist];
}
last line of code which should append plist name to path do not do its job. Plist is never created. Now, strange thing, i manage to create one few days ago using same code. After that, I only move this piece of code in AppDelegate because, I call this code from different places. I discovered that isn't working when I switch to 4.3 emulator and then also try it on iphone device. When I switch to 4.2 emulator it works because there is already a plist, however when I change its name (to create new one) nothing happens - meaning, list is not created. I also try moving code back to original place, but that didn't gave desired result.
Your code should not create a plist anyway, only return a path. In order to actually save a plist at the chosen path, you could choose several approaches, for example use the following method on NSDictionary:
- (void)saveDictionary
{
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:#"bla" forKey:#"test"];
NSString *path = [self datafilePath];
[dictionary writeToFile:path atomically:YES];
}
- (NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:#"somelist.plist];
}
I was trying to use a plist to store an array with the below code:
NSString *name = firstName.text;
NSString *path = [[NSBundle mainBundle] pathForResource:#"Names" ofType:#"plist"];
NSMutableArray *namesArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
[namesArray addObject:name];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
[paths release];
NSString *docDirPath = [documentsDirectory stringByAppendingPathComponent:#"Names.plist"];
[namesArray writeToFile:docDirPath atomically:YES];
namesArray = [[NSMutableArray alloc] initWithContentsOfFile:docDirPath];
This code seems to work. Using NSLog, I have found that after this code executes the plist contains what I want it to, however, my program crashes because it generates an EXC_BAD_ACCESS on a device, and on the simulator it just crashes without an explanation. Does anyone know why that might happen?
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES); //Auto-released array
NSString *documentsDirectory = [paths objectAtIndex:0];
[paths release]; //Oh noes!
You don't own the reference to paths, so don't release it. Remove [paths release] and I'll bet you're fine. You're crashing because the autorelease pool is releasing paths after you've already done it yourself.
Quoth the guide:
You only release or autorelease objects you own. You take ownership of an object if you create it using a method whose name begins with “alloc” or “new” or contains “copy” ... or if you send it a retain message.
Have you checked, at which place it is giving EXC_BAD_ACCESS error.
In your code there are two wrong things; those are.
The Plist file consists a dictionary not an array, Here in the code you are copying the file data to an array. and saving the array to the plist file.
Second one is you are releasing the "paths" array, with out completion of usage of it. you have to release that array at the end of the statements; like after updating the array to the file.
Regards,
Satya
I have a NSMutableArray, each item in this array is different class. In each class has many field such as CPPlot, identifier,... (I am using CorePlot to develop a stock application). Now I would like to store this NSMutableArray to load when user reopen application, this will load all the chart they used before.
I try to figure out how to do that in Stackoverflow. And I found out there were 2 solutions:
NSUserDefaults
SQLite database
In NSUserDefaults, when I want to store NSMutableArray, I must implement with NSKeyedArchiver to archive and unarchive array object, also do NSCoding protocol for each item in array object. But I can not do this solution because in each item, it has some fields from CorePlot library, so that I can not use NSCoding to these fields.
SQLite database, I can not use this solution because each item in array object is different class.
I would like to ask if any other solution to solve this problem?
I hope my words are clear enough to understand.
Thanks
I would suggest you figure out what kind of data is at the root of your CorePlot objects. If it is integers, then simply store them in NSUserDefaults, and then simply rebuild your NSMutableArray on re-opening the app. Another option is to store your items in a separate plist file.
Use this method to save:
- (NSArray *)applicationDataFromFile:(NSString *)fileName {
NSArray *paths = NSSearchPathForDirecotiresInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory
stringByAppendingPathComponent:fileName];
NSArray *myData = [NSArray arrayWithContentsOfFile:appFile];
return myData;
}
- (BOOL)saveToFileForStringArray:(NSMutableArray *)array
toFile:(NSString *)fileName {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
if (!documentsDirectory) {
NSLog(#"Documents directory not found!");
return NO;
}
NSString *appFile = [documentsDirectory
stringByAppendingPathComponent:fileName];
return ([array writeToFile:appFile atomically:YES]);
}
i can access .txt file from documents folder but how to access a folder content lets say documents/A
inside A i have ->a.html, update.cfg
now why i cant access update.cfg??
i am getting null value for zipPath
i tried this but no luck
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *aDirectory = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"A"];
NSString *zipPath = [[NSBundle mainBundle] pathForResource:#"update" ofType:#"cfg" inDirectory:aDirectory];
still zipPath=NULL??
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *aDirectory = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"A"];
My approach to get to the documentsfolder is a little bit different. (I hope you mean the Documents folder which every application has, not one created by yourself in the mainbundle.^^) I do it like this:
NSString *directoryPath = [[NSHomeDirectory() stringByAppendingPathComponent: #"Documents"] stringByAppendingPathComponent: #"A"];
This is the path to your directory called A in the documents folder. If you know the filename, than you can use another "stringByAppendingPathComponent". ;-) I hope it helps. Else ask again. :-D
after messing up i found this way to acces the file from folder
i got it
NSString *fileName = [NSString stringWithFormat:#"%#/update.cfg",
aDirectory];
NSString *content = [[NSString alloc] initWithContentsOfFile:fileName
usedEncoding:nil
error:nil];
thanks
I am developing an iPhone app with someone else. The app works fine for me, but he is running into a bug. We think this bug is related to the fact that he is getting multiple Application directories for this same app. In my ~/Library/Application Support/iPhone Simulator/User/Applications, I only have one folder at all times.
He says that he will get 3 or 4 directories when he is only working on this one app. We think this is our problem because our bug has to do with displaying images that are stored in the app's Documents folder. Does anyone know why he is ending up with multiple directories or how to stop it?
Edit:
Here is the code for writing the image to a file:
NSData *image = [NSData dataWithContentsOfURL:[NSURL URLWithString:[currentArticle articleImage]]];
NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *imagePath = [array objectAtIndex:0];
NSFileManager *NSFM = [NSFileManager defaultManager];
BOOL isDir = YES;
if(![NSFM fileExistsAtPath:imagePath isDirectory:&isDir])
if(![NSFM createDirectoryAtPath:imagePath attributes:nil])
NSLog(#"error");
imagePath = [imagePath stringByAppendingFormat:#"/images"];
if(![NSFM fileExistsAtPath:imagePath isDirectory:&isDir])
if(![NSFM createDirectoryAtPath:imagePath attributes:nil])
NSLog(#"error");
imagePath = [imagePath stringByAppendingFormat:#"/%#.jpg", [currentArticle uniqueID]];
[image writeToFile:imagePath atomically:NO];
And here is the code for getting the path when I need the image:
- (NSString *)imagePath
{
NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *imagePath = [array objectAtIndex:0];
return [imagePath stringByAppendingFormat:#"/images/%#.jpg", [self uniqueID]];
}
The app works great for me, but my partner says that the images don't show up intermittently, and he notices that he gets multiple directories in his Applications folder.
I had this problem (I was saving photos in the apps documents directory) and after every new build the directory get's renamed, so my paths were no longer valid. I cooked up these 2 functions (in my app delegate) that will give me a path for the file I want to save or load from the documents or temp directory. Even if the app directory changes, as long as you only store the file name and not the full path, and then use your helper functions to get the path when you need it later you will be ok. Here's my functions for this:
+ (NSString*)fullPathToFile:(NSString*)file {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:file];
}
+ (NSString*)fullPathToTemporaryFile:(NSString*)file {
return [NSTemporaryDirectory() stringByAppendingPathComponent:file];
}
Works like a charm.