iOS Saving an Array into .plist File.

TalShani

macrumors member
Original poster
Jun 29, 2010
45
0
Hey guys,
I have a View-Based application.
There I have a TextView, with some text, and a button that when I press it,
it loads an UIAlertView.
I customized the AlertView to have a text field,
The alert also have 2 buttons, Cancel, and Submit.
I built some code that when I press the button "Submit",
The app will save an array, that contains the TextView,
and the TextField that in the Alert.
The code:

Code:
- (NSString *) savePath
{
	NSArray *pathArray = 
	NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	return [[pathArray objectAtIndex:0] stringByAppendingPathComponent:@"save.plist"];
}

- (IBAction) saveMe
{
	UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:@"How would you like to call to your story?" 
														  message:@"-" delegate:self 
												cancelButtonTitle:@"Cancel" otherButtonTitles:@"Save", nil];
	UITextField *myTextField = [[UITextField alloc] initWithFrame:CGRectMake(12.0, 70.0, 260.0, 20.0)];
	[myTextField setBackgroundColor:[UIColor whiteColor]];
	[myAlertView addSubview:myTextField];
	myTextField.font = [UIFont fontWithName:@"Arial" size: 15.0];
	myTextField.text = nameForSave;
	[myAlertView show];
	[myTextField release];
	[myAlertView release];	
}
- (void)alertView:(UIAlertView *)myAlertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
	if (buttonIndex == 0)
	{
		NSLog(@"cancel");
	}
	else
	{
		NSLog(@"save");
		NSArray *values = [[NSArray alloc] initWithObjects:result.text,nameForSave,nil];
		[values writeToFile:[self savePath] atomically:YES];
		[values release];
	}
}
- result.text = TextView.
Somehow, when I'm trying to run it, Its giving me the error (on console):
2010-07-26 12:50:51.704 saveTest[8080:207] save
wait_fences: failed to receive reply: 10004003
And when I'm checking on the .plist file it not showing anything.
Hope you will answer me as soon as possible, Tal Shani.
* Sorry if there is any typos.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
24,638
61
Harrogate
When you say "result.text = TextView" what exactly do you mean? That it's a UITextView (if so please use the correct class names, accuracy in imperative). If so this is a problem: you cannot serialise arbitrary objects into a plist. You can only save the well documented plist types into a plist. If you are trying to encode the object look at NSCoder
 

TalShani

macrumors member
Original poster
Jun 29, 2010
45
0
When you say "result.text = TextView" what exactly do you mean? That it's a UITextView (if so please use the correct class names, accuracy in imperative). If so this is a problem: you cannot serialise arbitrary objects into a plist. You can only save the well documented plist types into a plist. If you are trying to encode the object look at NSCoder
Oh, sorry, I meant UITextView,
And what do you mean?
I thought that I can write to .plist file an array as the same way I'm loading an array from it,
Can you please explain me the problem in more specific explanation?
I didn't understand the sentence : you cannot serialize arbitrary objects into a plist, what do you mean?
I've read the documentation again, and I can see any problem with my code,
It says the classes works with WriteToFile is:
NSString, NSData, NSArray, or NSDictionary
My array is using NSString, so I can't find any problem with it.
Thanks again, Tal.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
24,638
61
Harrogate
I cannot explain it any more clearly that I have. If results.text is a UITextView then adding that to an array means it cannot be saved to a plist. You say it's an NSString which leads me to believe that results is a UITextView, not results.text. Again if this is the case you must be more precise and accurate. Expecting us to guess what you really mean when you type one thing and mean another is not a good way to go about getting help.
 

TalShani

macrumors member
Original poster
Jun 29, 2010
45
0
I cannot explain it any more clearly that I have. If results.text is a UITextView then adding that to an array means it cannot be saved to a plist. You say it's an NSString which leads me to believe that results is a UITextView, not results.text. Again if this is the case you must be more precise and accurate. Expecting us to guess what you really mean when you type one thing and mean another is not a good way to go about getting help.
result is a UITextView, how do you recommend to write it
into an array and it will work out just fine?
 

robbieduncan

Moderator emeritus
Jul 24, 2002
24,638
61
Harrogate
Then start simplfying what you have till you find the error. This is very basic debugging. Any competent programmer should be able to work this backwards. I'd start be removing all your extra views from the UIAlertView...
 

TalShani

macrumors member
Original poster
Jun 29, 2010
45
0
Then start simplfying what you have till you find the error. This is very basic debugging. Any competent programmer should be able to work this backwards. I'd start be removing all your extra views from the UIAlertView...
I did exactly what you said,
I started removing all the data until I got only the saving command,
Then I created NSLog's all over the app, so I will know what happens at every time,
I discovered that the issue is on the saving command:
Code:
- (NSString *) savePath
{
	NSArray *pathArray = 
	NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
	return [[pathArray objectAtIndex:0] stringByAppendingPathComponent:@"stories.plist"];
}
- (IBAction) saveMe
{
        stringByAppendingPathComponent:@"stories.plist"];
        NSLog(@"save");
        NSArray *values = [[NSArray alloc] initWithObjects:takeText.text,nil];
        [values writeToFile:[self savePath] atomically:YES];
        [values release];
}
Can you see any problem with the saving commands?
Hope to here from you soon,
Tal.
 

TalShani

macrumors member
Original poster
Jun 29, 2010
45
0
It is not compilable. It is not legal Objective-C. Either copy and paste the exact complete code you are using or accept that we are left guessing and cannot help.
I gave you to full code twice, plus the code of the error,
All the things that I published it is the entire code.
 

dejo

Moderator
Staff member
Sep 2, 2004
15,981
447
The Centennial State
robbieduncan is referring to the first line of your saveMe method (highlighted in red below):
Code:
- (IBAction) saveMe
{
        [B][COLOR="Red"]stringByAppendingPathComponent:@"stories.plist"];[/COLOR][/B]
        NSLog(@"save");
        NSArray *values = [[NSArray alloc] initWithObjects:takeText.text,nil];
        [values writeToFile:[self savePath] atomically:YES];
        [values release];
}
This is not a valid Objective-C statement and your code will not compile. What is it doing here?
 

TalShani

macrumors member
Original poster
Jun 29, 2010
45
0
robbieduncan is referring to the first line of your saveMe method (highlighted in red below):
Code:
- (IBAction) saveMe
{
        [B][COLOR="Red"]stringByAppendingPathComponent:@"stories.plist"];[/COLOR][/B]
        NSLog(@"save");
        NSArray *values = [[NSArray alloc] initWithObjects:takeText.text,nil];
        [values writeToFile:[self savePath] atomically:YES];
        [values release];
}
This is not a valid Objective-C statement and your code will not compile. What is it doing here?
Oh, I guess I had copy problem, this is the SaveMe action :
Code:
NSLog(@"save");
		NSArray *values = [[NSArray alloc] initWithObjects:takeText.text,nil];
		[values writeToFile:[self savePath] atomically:YES];
		[values release];
And this is the file path statement :
Code:
- (NSString *) savePath
{
	NSArray *pathArray = 
	NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	return [[pathArray objectAtIndex:0] stringByAppendingPathComponent:@"stories.plist"];
}
 

TalShani

macrumors member
Original poster
Jun 29, 2010
45
0
Alright. Now with the stripped down code, what exact problems are you seeing / what is not working?
It needs to add an array into .plist file (like 2 new objects),
It doesn't save it, no error, just don't work.
 

dejo

Moderator
Staff member
Sep 2, 2004
15,981
447
The Centennial State
It needs to add an array into .plist file (like 2 new objects)...
First of all, you are only supplying 1 object to your array (takeText.text), not 2.
Second, what do you mean by "adding an array into .plist"? Are you trying to append that information into an existing .plist?

It doesn't save it, no error, just don't work.
Then you need to follow robbieduncan's advice and start applying basic debugging methods to figure out why. Perhaps start by actually capturing the BOOL that writeToFile:atomically: returns and seeing if it is YES or NO.
 

TalShani

macrumors member
Original poster
Jun 29, 2010
45
0
First of all, you are only supplying 1 object to your array (takeText.text), not 2.
Second, what do you mean by "adding an array into .plist"? Are you trying to append that information into an existing .plist?


Then you need to follow robbieduncan's advice and start applying basic debugging methods to figure out why. Perhaps start by actually capturing the BOOL that writeToFile:atomically: returns and seeing if it is YES or NO.
I already debugged, That's how I discovered that the save doesn't work.
And yes, I need to add into an existing .plist the the array (stories.plist).
 

dejo

Moderator
Staff member
Sep 2, 2004
15,981
447
The Centennial State
I already debugged, That's how I discovered that the save doesn't work.
That's not really debugging. You discovered the code doesn't work as expected. Debugging is discovering why / where the code doesn't work as expected.

So, what have you done (please be specific) to determine the cause of the problem you are encountering?

And yes, I need to add into an existing .plist the the array (stories.plist).
Then you will need to do more than just writeToFile:atomically: which will overwrite the current contents of the .plist file.
 

TalShani

macrumors member
Original poster
Jun 29, 2010
45
0
That's not really debugging. You discovered the code doesn't work as expected. Debugging is discovering why / where the code doesn't work as expected.

So, what have you done (please be specific) to determine the cause of the problem you are encountering?


Then you will need to do more than just writeToFile:atomically: which will overwrite the current contents of the .plist file.
First, I cleaned the code, and stayed just with the things I need (Basic).
The I created breakpoints and NSLogs, so I can see exactly what is the things that don't work.

And the existing .plist file don't have any data in it, its blank, the app should add it.

Can you please help me solve this annoying problem?
Thanks, Tal.
 

TalShani

macrumors member
Original poster
Jun 29, 2010
45
0
What is the return value of your writeToFile:atomically: call?
Blank, I wrote the array to .plist file name "stories.plist",
at ObjectAtIndex:0.
Then I created an NSString that equals to the .plist file ObjectAtIndex:0,
An after that I showed the NSString on UITextField and it turned blank.
 

chown33

Moderator
Staff member
Aug 9, 2009
8,556
4,618
inter-prandial
Blank, I wrote the array to .plist file name "stories.plist",
at ObjectAtIndex:0.
Then I created an NSString that equals to the .plist file ObjectAtIndex:0,
An after that I showed the NSString on UITextField and it turned blank.
What is the length of the file, as stored at the pathname?

If you remove that file and run the program, is the file recreated? If so, then your file-writing code is working. The problem lies in the contents of the NSArray. If the file is not recreated, then you have a file-writing problem. Notice how I have broken the problem into two possible outcomes, and logically determined what each outcome means. This is a fundamental analysis skill.

If the file is recreated and has a non-zero length, then exactly what data is in the file? If it's an array with no elements, then that means your NSArray contained no elements when it was written. If it's an array with one string element, and the text of the string is "", then your NSArray contained @"" when it was written. Again, notice that I've broken the problem down into sub-components (contents of file, two possible interpretations of file contents), and logically determined what each one means.

If your array contains no elements, then takeText.text must be returning nil. If your array contains one "" element, then takeText.text must be returning @"". Here, I'm logically working backwards from the two possible outcomes, and making testable statements about how the NSArray 'values' came to have either zero or one element.

If takeText.text is nil, what might cause that?
One possibility is that takeText itself is nil. There are other possibilities. You have to look at the variables while debugging your code.

If takeText.text is an empty string, what might cause that?


A testable statement means an observable condition or state of some variable, whose answer can be determined by running the program in a debugger and actually observing what happens. If you can't determine the answer by observing something, then it's an untestable statement, and has no practical use because it can't be tested by any observation.

If a testable statement is too complex, it needs to be broken down into smaller testable statements. This is called decomposition and is fundamental to creating all software.

If you can't create testable statements about your code, then you probably don't understand what the code is doing, or what its sub-parts are doing. You fix this by learning what the code is doing. Otherwise it's all just magic, and you can't debug magic.


All the above is nothing but basic debugging logic and analysis. The logic means understanding the logical consequences of different observed states and outcomes (file exists or it doesn't; file contains some data or it doesn't; etc.). The analysis means working backwards from outcomes, and working forwards from existing state (a string variable is either nil or "" or some other text; an array contains either 0 or 1 elements; etc.).