write a dictionary to plist on iphone - iphone

I want to add a new dictionary to the existing plist file, how can I do that, I can read from the file, but with the same approach, writing doesn't work. My plist structure looks like this:
Root Array
|__item0 Dictionary
|__item1 Dictionary
|__item2 Dictionary
The code of writing to the file looks like this:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
NSString *plistPath = [documentDirectory stringByAppendingPathComponent:#"list.plist"];
if (![fileManager fileExistsAtPath:plistPath]) {
plistPath = [[NSBundle mainBundle] pathForResource:#"list" ofType:#"plist"];
}
NSMutableArray *dataRoot = [NSMutableArray arrayWithContentsOfFile:plistPath];
NSMutableDictionary *item = [[NSMutableDictionary alloc] init];
[item setObject:#"value1" forKey:#"1"];
[item setObject:#"value2" forKey:#"2"];
[item setObject:#"value3" forKey:#"3"];
[dataRoot addObject:item];
[dataRoot writeToFile:plistPath atomically:YES];
[item release];
Can anyone help me with this, thanks!
I have updated my code, but it still doesn't work...And the problem is list.plist file doesn't get copied to ~/Documents directory.

You are trying to write the main bundle which is no-no on iOS. Please read the A Few Important Application Directories.
But your coding boils down to the following:
Check if plist is not in Application_Home/Documents/
Copied original plist from main bundle is the answer to step 1 is false.
Open the plist in the Documents directory
Update NSMutableArray
Write to file the plist

I think code is not wrong.
Have you check plistPath, dataRoot, and item?
They have correct value?

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"list.plist"];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
bingoArray = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
}
[bingoArray writeToFile:filePath atomically:YES];

You can only save primitive types by default.
try out this link.
http://deadpanic.com/howtosave
He explains how to save any object to disk by using NSCoding protocol.
If you are working only with primitives then I apologize for wasting your time. But this is the path I took to write my custom stuff to disk. And I thought it was just an array issue.
Edit:
I just noticed... It looks like you are trying to write to an array in the Main Bundle. These files are read only.
You need to save a copy of the file in the Documents directory.
try this out to find the documents directory
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// Change your plistPath to be this
plistPath = [documentsDirectory stringByAppendingPathComponent:#"list.plist"];
[dataRoot writeToFile:plistPath atomically:YES];
put your plist in this folder and you can write to it.

Related

Settings.plist iOS

I have a Settings.plist file in my iOS application. I access it using this code below:
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"Settings.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path])
{
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"Settings" ofType:#"plist"];
[fileManager copyItemAtPath:bundle toPath: path error:&error];
}
NSMutableDictionary *savedStock = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
But, say I make some changes to the Settings.plist file in my application, like add another row. Then if I publish it, users that already have my app will have an out dated Settings.plist file. Any ideas on a workaround or anything? I have tried accessing the Settings.plist file straight from the NSString *bundle, but then the values don't "save".
You need to do a file modification date check, see my answer here. Then if the modification date is later than the last checked date, download the Settings.plist file and replace it in the users app.

Storing NSArray/NSMuatbleArray in File

I'm beginning to store an NSArray in file, but I keep getting nil as a response...
The Apple docs say that nil means your file doesn't exist, but I'm pretty sure mine does (I'm probably not building my path correctly)...
Here is the code that I use to store my NSArray in a file...
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"scorecards" ofType:#"dgs"];
NSArray *myArray = [[NSArray alloc] initWithObjects:#"J", #"ANA", #"MY", #"GDON", nil];
[myArray writeToFile:filePath atomically:YES];
NSArray *mynewArray = [NSArray arrayWithContentsOfFile:filePath];
NSLog(#"%#", [mynewArray objectAtIndex:2]);
I also took a screenshot of Xcode to show you guys that my file does exist...
The file is clearly saved in the group ScorecardsSaved and the file is called scorecards with the extension dgs (something I made up for my specific application - Dot Golf Scorecard - dgs)
Indeed, your file path uses the pathForResource method, thus it will point to a location in your application bundle, which is not writable.
Instead, you have to write to the application document directory on the device / simulator.
NSURL *documentsDirectory =
[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask] lastObject];
NSURL *fileURL = [documentsDirectory
URLByAppendingPathComponent:#"storecards.dgs"];
So if your bundle version of the document contains some seed data, copy it to the app documents directory first.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:FILE_NAME];
[myArray writeToFile:filePath atomically:YES];

can't creating plist file in document folder

I have write code like this in Viewdidload method. But it don't create file .plist.
I don't know whether code is wi8 or wrong. And where i have to write?
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; //2
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"data1.plist"]; //3
NSFileManager *fileManager = [NSFileManager defaultManager];
if ( ![fileManager fileExistsAtPath:path] ) {
NSString *pathToSettingsInBundle = [[NSBundle mainBundle]
pathForResource:#"data1" ofType:#"plist"];
}
You have just created a path to it, you should try loading it into a NSDictionary.
NSDictionary* mydictionary = [ NSDictionary dictionaryWithContentsOfFile: pathToSettingsInBundle];
Inside your if block add a second line
[fileManager copyItemAtPath:pathToSettingsInBundle toPath:path error:&error];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
plistpath = [[NSString alloc] initWithString:[documentsDirectory stringByAppendingPathComponent:#"Product.plist"]];
And then
[array writeToFile:path atomically:YES];
[Whatever [Array or Dictionary] you want to Write in Plist]
If it is still not creating the plist then check whether your array or dictionary must be empty.

How can I overwrite the contents of a plist file? (iPhone / iPad)

I have a plist file in my main app bundle that I want to update via my app. Here is the code I'm using, the problem is that the plist doesn't seem to be getting updated. Is my code incorrect or is there another issue?
// Data
NSMutableDictionary *data = [[NSMutableDictionary alloc] init];
[data setObject:self.someValue forKey:#"Root"];
// Save the logs
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"MyFile" ofType:#"plist"];
[data writeToFile:filepath atomically:YES];
Please can someone help me out?
IOS restricts writing to bundled files. If you want a writable plist, you need to copy it to your app's Documents folder and write to it there.
Here's how I'm doing it in one of my apps
//get file paths
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [documentPaths objectAtIndex:0];
NSString *documentPlistPath = [documentsDirectory stringByAppendingPathComponent:#"document.plist"];
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSString *bundlePlistPath = [bundlePath stringByAppendingPathComponent:#"bundle.plist"];
//if file exists in the documents directory, get it
if([fileManager fileExistsAtPath:documentPlistPath]){
NSMutableDictionary *documentDict = [NSMutableDictionary dictionaryWithContentsOfFile:documentPlistPath];
return documentDict;
}
//if file does not exist, create it from existing plist
else {
NSError *error;
BOOL success = [fileManager copyItemAtPath:bundlePlistPath toPath:documentPlistPath error:&error];
if (success) {
NSMutableDictionary *documentDict = [NSMutableDictionary dictionaryWithContentsOfFile:documentPlistPath];
return documentDict;
}
return nil;
}
Hope this helps

How to load PDFs from Documents Directory?

I can load list of pdf files(all pdf files) from Resources folder, using this code.
NSArray *pdfs = [[NSBundle mainBundle] pathsForResourcesOfType:#"pdf" inDirectory:nil];
But I couldn't find a method to load list of pdf files from Documents Directory. The following line of code can only load one pdf at a time.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *file = [documentsDirectory stringByAppendingPathComponent:#"test.pdf"];
NSURL *urlPdf = [NSURL fileURLWithPath: file];
How could I load all pdf files from Documents Directory
Can you please give me a code example.
I was able to solve my issue using this line of code :)
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSArray *pdfs = [[NSBundle bundleWithPath:[paths objectAtIndex:0]] pathsForResourcesOfType:#"pdf" inDirectory:nil];
Go with NSFileManager's contentsOfDirectoryAtPath and filter the result by hand for pdf files.
This answer maybe helpful.
You could do this
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
NSArray *filesAtPath = [fileManager contentsOfDirectoryAtPath:documentsDirectory error:error];
for (NSString *path in filesAtPath)
{
if ([path rangeOfString:#".pdf"].length > 0)
{
//Do whatever you want with the pdf file
}
}
I hope it helps, cheers