Increment Number in plist - iphone

I am using the method below to get an array from my plist and then increase a certain value by 1, then save it. However I log the array and the value doesn't actually go up each time.
In my plist, I have an array and in that number values, each one is set to 0. So every time I run this again it goes back to 0 it seems.
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:#"Words.plist"];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:finalPath];
NSMutableArray *errors = [dict objectForKey:[NSString stringWithFormat:#"Errors%d.%d", [[stageSelectionTable indexPathForSelectedRow] section] +1, [[stageSelectionTable indexPathForSelectedRow] row] +1]];
int a = [[errors objectAtIndex:wordIndexPath] intValue];
a += 1;
NSNumber *b = [NSNumber numberWithInt:a];
[errors replaceObjectAtIndex:wordIndexPath withObject:b];
[errors writeToFile:finalPath atomically:YES];

You can only write to a file in the documents-folder. You can't write to your bundle!
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"Namelist.plist"];
You can use NSFilemanager to copy your Plist-File to the documents-folder.
To get the path of your file:
- (NSString *)filePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"MyFile.plist"];
return filePath;
}
To copy the file if it doesn't exist:
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:[self filePath]]) {
NSString *path = [[NSBundle mainBundle] pathForResource:#"MyFile" ofType:#"plist"];
[fileManager copyItemAtPath:path toPath:[self filePath] error:nil];
}
Now you can write your NSDictionary to the Documents-Directory:
[dict writeToFile:[self filePath] atomically:YES];
But you really need to update the array in the dict!

You are writing the array to disk, instead of the dictionary that the array originated from:
[dict writeToFile:finalPath atomically:YES];
Also, you will need to replace the Errors%d.%d object with the updated one before saving it:
[dict setObject:errors forKey:/* your formatted key*/];
Finally, as #mavrick3 pointed out, you cannot save files to your bundle, only to your application's documents directory.

Related

Creating an array of dictionaries plist

I am creating a plist of dictionaries. The plist starts off as empty, and then I do this:
NSMutableArray *favouritesList = [[NSMutableArray alloc] initWithContentsOfFile:path];
[favouritesList addObject:thisPlace]; // where thisPlace is some NSDictionary
[favouritesList writeToFile:path atomically:YES];
When I immediately do:
NSArray *savedFav = [[NSArray alloc] initWithContentsOfFile:path];
NSLog(#"%#", savedFav);
I get an empty array. Why is this? Why isn't it writing properly? I am setting up the plist correctly, I debugged that. But I cannot add a dictionary to it.
The plist is just an empty plist with a root that's an array
EDIT:
Here is how I construct my path:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"favourites.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:path]) {
NSString *sourcePath = [[NSBundle mainBundle] pathForResource:#"favourites" ofType:#"plist"];
[fileManager copyItemAtPath:sourcePath toPath:path error:nil];
}
I do something like below. I add an object using a key. Maybe that's why it's not working.
static NSMutableDictionary *dictionaryStore;
+(void)initialize{
if(dictionaryStore == nil){
dictionaryStore = [[NSMutableDictionary alloc] initWithContentsOfFile:[self getFilePath]];
if(dictionaryStore == nil)
dictionaryStore = [NSMutableDictionary new];
}
}
+(NSString *)getFilePath{
NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *plistPath = [rootPath stringByAppendingPathComponent:#"filename.plist"];
return plistPath;
}
+(NSString *)getValueForKey:(NSString *)key{
[self initialize];
return [dictionaryStore objectForKey:key];
}
+(void)setValue:(NSString *)value forKey:(NSString *)key{
[self initialize];
[dictionaryStore setValue:value forKey:key];
}
+(BOOL)save{
[self initialize];
return [dictionaryStore writeToFile:[self getFilePath] atomically:YES];
}
Edit:
So to save a value, I do:
[WAStore setValue:myValue forKey:myKey];
BOOL isSuccessful = [WAStore save];
WAStore is the class name. myValue can be most data types (NSManagedObjectModels won't work). myKey is any NSString.

How to retrive an object name from an array if I have index number in objective-C?

I have an array by all the objects. I don't know which index contain which object. When I use this array I just use index number. How to find name of object at that index?
NSString *extension = #"png";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray *contents = [fileManager contentsOfDirectoryAtPath:documentsDirectory error:nil];
NSMutableArray *pngFiles = [NSMutableArray arrayWithCapacity: [contents count]];
NSString *filename;
for (filename in contents)
{
if ([[filename pathExtension] isEqualToString:extension])
{
[pngFiles addObject:[UIImage imageWithContentsOfFile:[documentsDirectory stringByAppendingPathComponent:filename]]];
}
}
Instead of using an array use a dictionary. So you can save that image name and image
[pngFiles setObject:[UIImage imageWithContentsOfFile:[documentsDirectory stringByAppendingPathComponent:filename]] forKey:filename];

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.

NSMutableDictionary

How to use NSMutable Dictionary in another class for read and write data from plist file in iphone....
Any Ideas?
As you can find in in NSDictionary reference, this class has a method to create a nsdictionary from a file initWithContentsOfFile:(NSString *)path . You can do something like:
NSString *plistPath = [[NSBundle mainBundle] pathForResource:#"myDictionary" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
Where myDictionary is your plist name (In case of your plist is inside resource bundle).
You can write a plist on disk with the method:
[dict writeToFile:filePath atomically: YES];
Where filePath is your destination path.
See the Plist files example on this tutorial.
// Look in Documents for an existing plist file
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
myPlistPath = [documentsDirectory stringByAppendingPathComponent:
[NSString stringWithFormat: #"%#.plist", plistName] ];
[myPlistPath retain];
// If it's not there, copy it from the bundle
NSFileManager *fileManger = [NSFileManager defaultManager];
if ( ![fileManger fileExistsAtPath:myPlistPath] ) {
NSString *pathToSettingsInBundle = [[NSBundle mainBundle]
pathForResource:plistName ofType:#"plist"];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *path = [documentsDirectoryPath
stringByAppendingPathComponent:#"myApp.plist"];
NSMutableDictionary *plist = [NSDictionary dictionaryWithContentsOfFile: path];
myKey = (int)[[plist valueForKey:#"myKey"] intValue];
myKey2 = (bool)[[plist valueForKey:#"myKey2"] boolValue];
[plist setValue:myKey forKey:#"myKey"];
[plist writeToFile:path atomically:YES];

check if plist exist, if not load from here

I am trying to check whether a plist exists in my doc folder: if yes, load it, if not load from resource folder.
- (void)viewWillAppear:(BOOL)animated
{
//to load downloaded file
NSArray *docpaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [docpaths objectAtIndex:0];
NSString *docpath = [documentsDirectory stringByAppendingPathComponent:#"downloadedfile.plist"];
//if document folder got file
if(docpath != nil)
{
NSDictionary *dict = [[NSDictionary alloc]
initWithContentsOfFile:docpath];
self.allNames = dict;
[dict release];
}
//on error it will try to read from disk
else {
NSString *path = [[NSBundle mainBundle] pathForResource:#"resourcefile"
ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc]
initWithContentsOfFile:path];
self.allNames = dict;
[dict release];
}
[table reloadData];
Where did I go wrong? The plist is not loading from resource folder.
I think if you create an instance of NSFileManager you can then use the file exists method
BOOL exists;
NSFileManager *fileManager = [NSFileManager defaultManager];
exists = [fileManager fileExistsAtPath:docPath];
if(exists == NO)
{
// do your thing
}
You need to check wether the file exists in your Documents folder (with NSFileManager or something like this). stringByAppendingPathComponent: doesn’t care wether the path it returns exists or is valid.
I have used a similar approach in one of the applications and it was working fine for me. Where at the launch of the application, I check for the plist file inside the document directory and if it does not exists there, then it is copied from the resource folder.
NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString * plistName = #"FlowerList";
NSString * finalPath = [basePath stringByAppendingPathComponent:
[NSString stringWithFormat: #"%#.plist", plistName]];
NSFileManager * fileManager = [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:finalPath])
{
NSError *error;
NSString * sourcePath = [[NSBundle mainBundle] pathForResource:#"FlowerList" ofType:#"plist"];
[fileManager copyItemAtPath:sourcePath toPath:finalPath error:&error];
}
Here is the Swift version of Chris's Answer:
if (NSFileManager.defaultManager().fileExistsAtPath(path)) {
// ...
}