iOS Adding Array to Plist Document Root - ios

Okay so after feedback I am doing this changes to my code it's working but just adding and replacing the first one?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *user_id = [prefs objectForKey:#"user_id"];
NSString *fixture_id = [prefs objectForKey:#"fixture_id"];
// Get path to documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
if ([paths count] > 0)
{
NSString *selectedPath = [[paths objectAtIndex:0]
stringByAppendingPathComponent:[NSString stringWithFormat:#"%#-%#",user_id, fixture_id]];
// Read both back in new collections
self.mySelectionsArray = [NSArray arrayWithContentsOfFile:selectedPath];
NSLog(#"Players Selected = %#", self.mySelectionsArray);
}
NSDictionary *tempDic = [[[self.listOfPlayersArray objectAtIndex:indexPath.section] objectForKey:#"contacts"] objectAtIndex:indexPath.row];
NSString *avatar = [tempDic objectForKey:#"avatar"];
NSString *avatarSmall = [tempDic objectForKey:#"avatar_small"];
NSString *first_name = [tempDic objectForKey:#"first_name"];
NSString *last_name = [tempDic objectForKey:#"last_name"];
NSDictionary *innerDic;
innerDic = [NSDictionary dictionaryWithObjects:
[NSArray arrayWithObjects: avatar, avatarSmall, first_name, last_name, nil]
forKeys:[NSArray arrayWithObjects:#"avatar", #"avatar_small", #"first_name", #"last_name", nil]];
self.mySelectionsArray = [NSMutableArray arrayWithObject:[NSDictionary dictionaryWithDictionary:innerDic]];
// [self.mySelectionsArray insertObject:innerDic atIndex:0];
[self.mySelectionsArray addObject:innerDic];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if ([paths count] > 0)
{
// Path to save array data
NSString *arrayPath = [[paths objectAtIndex:0]
stringByAppendingPathComponent:[NSString stringWithFormat:#"%#-%#",user_id, fixture_id]];
NSLog(#"Path: %#",arrayPath);
// Write array
[self.mySelectionsArray writeToFile:arrayPath atomically:YES];
}
[self dismissViewControllerAnimated:YES completion:nil];
}
Which is now checking for array and pulling it down then adding the object
The plist looks like this after selecting a player;
{
"first_name" = Ollie;
"last_name" = Akroyd;
},
{
"first_name" = Ollie;
"last_name" = Akroyd;
}
)

Stated your code, mySelections is empty, I guess you want to add innerDic to it; moreover you are saving mySelections instead of userSelections.
You should add innerDic to mySelections and save userSelections to resolve your issue.
EDIT
Instead of
self.mySelectionsArray = [NSMutableArray arrayWithObject:[NSDictionary dictionaryWithDictionary:innerDic]];
which overrides the read array, add the object:
[self.mySelectionsArray addObject:innerDic];
self.mySelectionsArray must be mutable, so instead of
self.mySelectionsArray = [NSArray arrayWithContentsOfFile:selectedPath];
write
self.mySelectionsArray = [[NSArray arrayWithContentsOfFile:selectedPath] mutableCopy];

Related

add string dynamically in objc

I want to add string value dynamically from result.text and I wanted to display it in this way [#"17052648287",#"17052607335"] without losing the value. How can I do it?
NSMutableArray *strings = [#[#"17052648287",#"17052607335"] mutableCopy];
Add on coding
- (void)captureResult:(ZXCapture *)capture result:(ZXResult *)result{
if (!result) return;
if(self.hasScannedResult == NO)
{
//Scan Result, added into array
NSString *scanPackage = [NSString stringWithFormat:#"%#", result.text];
scanLists = [NSMutableArray new];
[scanLists addObject:scanPackage];
NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults];
NSMutableArray *strings = [[NSMutableArray alloc]init];
strings = [#[result.text] mutableCopy];
[preferences setObject:strings forKey:#"strings"];
NSMutableArray *stringsArray = [preferences objectForKey:#"strings"];
for (NSString *string in stringsArray) {
NSLog(#"string: %#", string);
}
Declare an results array:
NSMutableArray * array = [NSMutableArray new];
Write below code where you get your result.text:
NSString *scanPackage = [NSString stringWithFormat:#"%#", result.text]; // If this code is working for you
[array addObject: scanPackage];
NSString *combined = [array componentsJoinedByString:#","];
NSLog(#"combined: %#", combined);

How can I detect an error when searching through a property list?

On the first screen of my app, you enter a 4 digit code. When you press "Done", it saves the code automatically and the app switches views to the next screen. On the new screen, it pulls up the saved code and searches through a plist trying to find the string it's associated with. It currently works perfectly except for when the user enters a code that is not in the plist.
How can I teach it to give an error alert of the code is not present in the plist?
This is the first view:
NSString *pureString = [[detectionString componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:#""];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:pureString forKey:#"beaverID"];
[defaults synchronize];
ViewController *Flip = [[ViewController alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:Flip animated:YES];
Then in the second view:
- (void)viewDidLoad {
//Loading the unique student's ID code:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *loadstring = [defaults objectForKey:#"beaverID"];
//Loading the user's first name from the first .plist:
NSString *error2 = nil;
NSPropertyListFormat format2;
NSString *plistPath2;
NSString *rootPath2 = [NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSString *file2 = #"User Data.plist";
plistPath2 = [rootPath2 stringByAppendingPathComponent:file2];
if (![[NSFileManager defaultManager] fileExistsAtPath:plistPath2]) {
plistPath2 = [[NSBundle mainBundle] pathForResource:#"User Data" ofType:#"plist"];
}
NSData *plistData2 = [[NSFileManager defaultManager] contentsAtPath:plistPath2];
NSDictionary *tempDict2 = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:plistData2 mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format2 errorDescription:&error2];
NSString *person = [#"BCDS" stringByAppendingString:loadstring];
NSString *string = [tempDict2 objectForKey:person];
NSString *message = [#"Hello, " stringByAppendingString:string];
welcome.text = message;
}
Just check if objectForKey returns nil:
NSString *string = [tempDict2 objectForKey:person];
if (string == nil)
[[[UIAlertView alloc]
initWithTitle:#"Error" message:#"Cannot find item"
delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] show];

Saved data getting replaced by new data on app relaunch

I am making a calorie counter which displays the total calorie count of various foods added. I have written code to save data following this tutorial. When I relaunch the app I can see the calorie count is the same as when I quit the app but when I add a new food item, the calorie count is reset and the count begins from the start. Why is the value not being saved??
EDIT:
This is a snippet of my code:
if(alertView.tag == ChickenAlertView) {
NSString *buttonTitle = [alertView buttonTitleAtIndex:buttonIndex];
if([buttonTitle isEqualToString:#"Ok"]){
float chicken= ([ChickenText.text floatValue]);
currentnumber = (chicken/100)*219;
result = result + currentnumber;
calories.text= [[NSString alloc] initWithFormat:#"%.f",result];
}
}
From NSLog, i can see the value of result is going to 0 every time I relaunch the app. How do I prevent it?
This is where I save the code:
- (NSString *) saveFilePath {
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [[path objectAtIndex:0] stringByAppendingPathComponent:#"savefile.plist"];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSArray *values = [[NSArray alloc] initWithObjects: NameLabel.text, AgeLabel.text, HeightLabel.text, WeightLabel.text, BMILabel.text, calories.text, [NSNumber numberWithFloat:result], nil];
[values writeToFile:[self saveFilePath] atomically:YES];
[values release];
}
- (void)viewDidLoad
{
foodData = [[foodData alloc]init];
NSString *myPath = [self saveFilePath];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:myPath];
if (fileExists)
{
NSArray *values = [[NSArray alloc] initWithContentsOfFile:myPath];
NameLabel.text = [values objectAtIndex:0];
AgeLabel.text = [values objectAtIndex:1]
HeightLabel.text = [values objectAtIndex:2];
WeightLabel.text = [values objectAtIndex:3];
BMILabel.text = [values objectAtIndex:4];
calories.text = [values objectAtIndex:5];
result = [[values objectAtIndex:6] floatValue];
[values release];
}
UIApplication *myApp = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:myApp];
[super viewDidLoad];
}

memory leak in NSArray, trace for long time

There are memory leaks in the below self.listOfCustDetail and self.listOfCustomer
-(void) calCustList {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *plistPath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"customer.plist"];
self.listOfCustDetail = [[[NSMutableArray alloc] init] autorelease];
self.listOfCustomer = [[[NSMutableArray alloc] init] autorelease];
self.customers = [[[NSMutableDictionary alloc] initWithContentsOfFile:plistPath] autorelease];
[self.listOfCustomer removeAllObjects];
[self.listOfCustDetail removeAllObjects];
[self.listOfCustomer addObject:#"新紀錄"];
[self.listOfCustDetail addObject:#""];
for (id key in self.customers) {
NSString *s = [NSString stringWithFormat:#"%#,%#,%#,%#", [[self.customers objectForKey:key] objectAtIndex:0], [[self.customers objectForKey:key] objectAtIndex:1], [[self.customers objectForKey:key] objectAtIndex:2], [[self.customers objectForKey:key] objectAtIndex:3]];
[self.listOfCustomer addObject:key];
[self.listOfCustDetail addObject:s];
}
}
How are your properties definied? do they retain? If they do retain, there is no actual mistake in the piece of code, that you are showing.
How often is that method called? If it is called very often you could use a custom NSAutoreleasePool.
Also the following two lines are not needed on a newly initalized array:
[self.listOfCustomer removeAllObjects];
[self.listOfCustDetail removeAllObjects];
Are you showing the actual sourcecode?
I would like to suggest,enable ARC(auto reference counting) in Project because you no need To release arrays

Writing new keys to a .plist file based on textField

What I want to do is to populate a pickerView from an array based on a .plist, which can be added to from a textField. I've got it to work, but it only adds one key and replaces it when a new one is added. For instance if I add "hello", and then try to add another one, it replaces hello with something else.
- (IBAction)setContext:(id)sender {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [[NSBundle mainBundle] pathForResource:#"fullArray" ofType:#"plist"];
NSString *textFieldText = textField.text;
NSMutableDictionary *rootDict = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
[rootDict setValue:textField.text forKey:textField.text];
NSString *writablePath = [documentsDirectory stringByAppendingPathComponent:#"fullArray.plist"];
[rootDict writeToFile:writablePath atomically: YES];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //1
NSString *plistPath = [documentsDirectory stringByAppendingPathComponent:#"fullArray.plist"]; //3
NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
NSArray *array = [dictionary allKeys];
arrayContext = [[NSMutableArray alloc] initWithArray:array];
[pickerView selectRow:0 inComponent:0 animated:YES];
[textField endEditing:YES];
[pickerView reloadAllComponents];
}
How can I fix this?
Ok, you are creating a new NSMutableDictionary every time you pick something in the picker, the correct approach is:
Create a NSMutableDictionary as a property.
Every time you pick, create a new string for the key, maybe using [NSString stringWithFormat:].
use [mutableDictionary setObject:forKey] for set a new object in the mutant dictionary, with the new created key.

Resources