Register FAQ / Rules Forum Spy Search Today's Posts Mark Forums Read
Go Back   MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Jan 3, 2013, 02:10 PM   #1
Mvkoe
macrumors member
 
Join Date: Aug 2008
Location: Belgium
Saving to Plist file.

Hey

As I'm getting a bit better and understanding some things more and more. I'm in this situation where I want to add new strings to my tableview.

So I've setted up everything, and made an addViewController with a textfield etc. When someone presses the button this will be the Action:
Code:
-(IBAction)doneKnop:(id)sender{
    NSString *myString = vraagVeld.text;
    [arrayData addObject:myString];
    [arrayData writeToFile:@"opties.plist" atomically:NO];
    [[self navigationController] popViewControllerAnimated:YES];
}
and at the beginning, i init my array plist:
Code:
- (void)viewDidLoad
{
    [super viewDidLoad];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"opties" ofType:@"plist"];
    NSMutableArray *data = [[NSMutableArray alloc] initWithContentsOfFile:path];
    self.arrayData = data;
}
But it seems to not write the file ? What am i doing wrong ?

Grz

Last edited by Mvkoe; Jan 7, 2013 at 11:48 AM.
Mvkoe is offline   0 Reply With Quote
Old Jan 3, 2013, 03:47 PM   #2
larswik
macrumors 65816
 
Join Date: Sep 2006
Where do you think you are saving the file to?

BTW, here are the documents from the apple site. Look up writeToFile and see what the requirements are for that method. The answer it there.

https://developer.apple.com/library/...occ/cl/NSArray
__________________
I know more than yesterday.
Lars
larswik is offline   0 Reply With Quote
Old Jan 3, 2013, 04:03 PM   #3
Mvkoe
Thread Starter
macrumors member
 
Join Date: Aug 2008
Location: Belgium
Quote:
Originally Posted by larswik View Post
Where do you think you are saving the file to?

BTW, here are the documents from the apple site. Look up writeToFile and see what the requirements are for that method. The answer it there.

https://developer.apple.com/library/...occ/cl/NSArray
I've looked it up so i've changed my path a bit:
Code:
-(IBAction)doneKnop:(id)sender{
    
    NSString *myString = vraagVeld.text;
    
    [arrayData addObject:myString];
    
    NSString *path = [[NSBundle mainBundle] pathForResource:@"opties" ofType:@"plist"];
    
    [arrayData writeToFile:path atomically:YES];
    
    NSLog(@"%@", arrayData);

    [[self navigationController] popViewControllerAnimated:YES];
}
and when I check my array it's in there by this:
Code:
(
    "Wie betaald?",
    "Wie is bob?",
    "Wie is Wat?",
    "Wie ben ik?",
    blah
)
But it seems not to write it .. Am i still doing something wrong?
Mvkoe is offline   0 Reply With Quote
Old Jan 3, 2013, 05:08 PM   #4
TheWatchfulOne
macrumors regular
 
Join Date: Jun 2009
What exactly is happening (or not happening) that makes you feel your file is not being written?

The more details you give about what you've tried, the better the help you will receive.
__________________
13" MacBook Pro, 2.26 GHz, 4 GB RAM, 500 GB HD iPhone 4 32GB 2nd gen iPod nano 4GB
TheWatchfulOne is offline   0 Reply With Quote
Old Jan 3, 2013, 05:40 PM   #5
PhoneyDeveloper
macrumors 68020
 
PhoneyDeveloper's Avatar
 
Join Date: Sep 2008
Your application bundle is read-only. On the device you can't write a file there. You should decide on a location for your plist file that is in your Application Support folder. When your app launches check if the file exists in the Application support folder. If it isn't there then copy the version from your bundle to the Application Support folder. After that always read/write the file from the Application Support folder.

BTW, writeToFile: returns a value telling you if it worked. You should inspect that value.
PhoneyDeveloper is offline   0 Reply With Quote
Old Jan 4, 2013, 03:31 AM   #6
Mvkoe
Thread Starter
macrumors member
 
Join Date: Aug 2008
Location: Belgium
Quote:
Originally Posted by PhoneyDeveloper View Post
Your application bundle is read-only. On the device you can't write a file there. You should decide on a location for your plist file that is in your Application Support folder. When your app launches check if the file exists in the Application support folder. If it isn't there then copy the version from your bundle to the Application Support folder. After that always read/write the file from the Application Support folder.

BTW, writeToFile: returns a value telling you if it worked. You should inspect that value.
Okay so I'm doing it wrong. I'm trying to write to my main bundle. What i'm trying to do is, adding a new row to my table view.

So what I need to do is.
  1. Always check if the plist is in the Application support folder of my app, if it isn't there copy it over there.
  2. Only work with the Application support plist, where i can read write from it?

Am I right?

EDIT:
Okay, so it's working now, i can read and write to it. But now the problem is, that my TableView doesn't update.

When i press the done button:
Code:
[[self navigationController] popViewControllerAnimated:YES];
Will execute, but this seems to not update my TableView, it only updates when i close the app and reopen it.

Last edited by Mvkoe; Jan 4, 2013 at 04:07 AM.
Mvkoe is offline   0 Reply With Quote
Old Jan 4, 2013, 07:39 AM   #7
PhoneyDeveloper
macrumors 68020
 
PhoneyDeveloper's Avatar
 
Join Date: Sep 2008
The usual way to update a table view with new data is to 1, update your data model, 2, [self.tableView reloadData].
PhoneyDeveloper is offline   0 Reply With Quote
Old Jan 4, 2013, 11:30 AM   #8
Mvkoe
Thread Starter
macrumors member
 
Join Date: Aug 2008
Location: Belgium
Quote:
Originally Posted by PhoneyDeveloper View Post
The usual way to update a table view with new data is to 1, update your data model, 2, [self.tableView reloadData].
Thanks for the help, I already figured it out by searching a bit, and remaking the adding, because the self.tableview can't be used in my adding vc.
Mvkoe is offline   0 Reply With Quote
Old Jan 4, 2013, 11:54 AM   #9
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
Quote:
Originally Posted by Mvkoe View Post
...because the self.tableview can't be used in my adding vc.
All the more reason to be using a model layer. A viewController updates the model data and then another viewController retrieves that model data.
__________________
dejo is offline   0 Reply With Quote
Old Jan 4, 2013, 05:12 PM   #10
Mvkoe
Thread Starter
macrumors member
 
Join Date: Aug 2008
Location: Belgium
Quote:
Originally Posted by dejo View Post
All the more reason to be using a model layer. A viewController updates the model data and then another viewController retrieves that model data.
Mmm oke, that should do it then. Got any book or tutorial where this is covered ?
Mvkoe is offline   0 Reply With Quote
Old Jan 4, 2013, 05:44 PM   #11
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
Have you finished reading "Beginning iOS 5 Programming" yet? That's the David Mark / Jack Nutting / Jeff LaMarche one you have, yes?

P.S. Be sure to check out this Apple doc as well: Concepts in Objective-C Programming
__________________
dejo is offline   0 Reply With Quote
Old Jan 4, 2013, 08:06 PM   #12
Mvkoe
Thread Starter
macrumors member
 
Join Date: Aug 2008
Location: Belgium
Quote:
Originally Posted by dejo View Post
Have you finished reading "Beginning iOS 5 Programming" yet? That's the David Mark / Jack Nutting / Jeff LaMarche one you have, yes?

P.S. Be sure to check out this Apple doc as well: Concepts in Objective-C Programming
I'm almost done with it, read the basics till chapter 10: Storyboarding. The model layer that you're saying, in what chapter like would it been discussed ? would it be in "Basic Data Persistence" ?
Mvkoe is offline   0 Reply With Quote
Old Jan 4, 2013, 11:26 PM   #13
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
Slow down, don't get ahead of yourself, step away from the real coding and finish reading the book. Make sure you're comfortable with everything it's covered. If not, read it again. Take working apps and tweak things. Read through that Apple doc I linked to. Figure out what areas you need to dig deeper in to understand. Take it easy.
__________________
dejo is offline   0 Reply With Quote
Old Jan 5, 2013, 03:38 AM   #14
Mvkoe
Thread Starter
macrumors member
 
Join Date: Aug 2008
Location: Belgium
Quote:
Originally Posted by dejo View Post
Slow down, don't get ahead of yourself, step away from the real coding and finish reading the book. Make sure you're comfortable with everything it's covered. If not, read it again. Take working apps and tweak things. Read through that Apple doc I linked to. Figure out what areas you need to dig deeper in to understand. Take it easy.
Hehe oke, It's just that I'm happy that most of the stuff work that I try, and want to build upon that as fast as I can sometimes. The only problem is that I'm dutch, and sometimes think like, hmm i need to find a "easy" explenation about something or a "this is it, and this is how it works" straight to the point.

So the Model Layer, is an NSobject class, that i need to alloc and init in each class i want to use. Then with getters and setter using the class ?

Like this?:
http://developer.apple.com/library/i...011318-CH9-SW1

EDIT:

Okay so it's going quite well! I'm almost getting there, so i have made a model layer with all my data things in. I can get it in my tableview etc, but now i got one problem. When adding something new to my tableview it gives an error that i don't understand:

Code:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'
But I'm doing a NSString with addObject to my NSMutableArray like this:

Code:
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
    if(buttonIndex == 1){
        NSString *naarArray = [actionSheet textFieldAtIndex:0].text;
        [self.dataController.vraagArray addObject:naarArray];
        [self.dataController saveData];
        [self.tableView reloadData];
    }
}

Last edited by Mvkoe; Jan 5, 2013 at 05:42 AM.
Mvkoe is offline   0 Reply With Quote
Old Jan 5, 2013, 10:45 AM   #15
PhoneyDeveloper
macrumors 68020
 
PhoneyDeveloper's Avatar
 
Join Date: Sep 2008
That error says that somewhere in your code there is a call to insertObject:AtIndex: on an NSArray. That method can only be called on an NSMutableArray.

Look up the words mutable and immutable and understand how they apply to all the container classes in Foundation Kit.

You need to verify the place in your code that this error is occurring. One way to do that is to set a breakpoint on All Exceptions and then run the app in the debugger until you get the error. At that point the app will be stopped in the debugger and you should see the stack trace in the debugger stack trace view. Another way is to run the app outside the debugger on the device and get a crash log.
PhoneyDeveloper is offline   0 Reply With Quote
Old Jan 5, 2013, 11:35 AM   #16
Mvkoe
Thread Starter
macrumors member
 
Join Date: Aug 2008
Location: Belgium
Quote:
Originally Posted by PhoneyDeveloper View Post
That error says that somewhere in your code there is a call to insertObject:AtIndex: on an NSArray. That method can only be called on an NSMutableArray.

Look up the words mutable and immutable and understand how they apply to all the container classes in Foundation Kit.

You need to verify the place in your code that this error is occurring. One way to do that is to set a breakpoint on All Exceptions and then run the app in the debugger until you get the error. At that point the app will be stopped in the debugger and you should see the stack trace in the debugger stack trace view. Another way is to run the app outside the debugger on the device and get a crash log.
You I tought that too, but the problem is that i don't use an NSArray, the only NSArray that i use if for my path loading, and that is done without error.

I'll try setting a breakpoint, to bad i don't have expierence with breakpoints..

EDIT:

Okay so i've setted a breakpoint, did it step by step, seems all fine by me, putting an NSString in my @property (nonatomic, copy) NSMutableArray *data;

And then suddenly it jumps to this code:
Code:
#import <UIKit/UIKit.h>

#import "AppDelegate.h"

int main(int argc, char *argv[])
{
    @autoreleasepool {
    ->>>>>>    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}
EDIT:

Hmm okay, by changing my @property (nonatomic, copy) to @property (nonatomic, strong) it works.. But it was told to me that you should always use copy as best option for Strings,arrays etc.. How come i need to use Strong in this case ? Can someone explain ?

Last edited by Mvkoe; Jan 5, 2013 at 12:42 PM.
Mvkoe is offline   0 Reply With Quote
Old Jan 5, 2013, 01:58 PM   #17
PhoneyDeveloper
macrumors 68020
 
PhoneyDeveloper's Avatar
 
Join Date: Sep 2008
Hoist by his own petard.

What do you think this does?

Code:
_myMutableArray = [[[NSMutableArray alloc] init] copy];
What is the class of _myMutableArray?

When you're stopped at a breakpoint move the slider at the bottom of the pane all the way to the right so you can see the full stack trace.
PhoneyDeveloper is offline   0 Reply With Quote
Old Jan 5, 2013, 06:41 PM   #18
larswik
macrumors 65816
 
Join Date: Sep 2006
Mvkoe - If you are on Chapter 10 of that book you should have a good idea of what mutable and immutable are like NSArray and NSMutableArray. I would slow down and even start over in the book and really get it. dejo mentioned that you should understand what you are reading before you move on, and it is a good idea.

When I was learning I did the same thing you are doing now and reading your posts sounds familiar. If you treat programming like a race you will lose. It sounds like you are reading every chapter and before you understand the material you are moving on and skipping over what you don't understand.

Your probably copying and pasting lots of code from the internet to Frankenstein your program together. If you are truly coming from a Java background then the cross over should not be that hard. Java deals with mutable and immutable object too.

I would go back to square one and really understand every chapter by writing lots of small programs that cover the material in that chapter. That is what was recommended to me when I started but I thought that knew better and soon I was asking for help like you are now because I did not get it.

My 2 cents if you want to be a good programmer, which I hope to be some day too.
__________________
I know more than yesterday.
Lars
larswik is offline   1 Reply With Quote
Old Jan 6, 2013, 04:07 AM   #19
Mvkoe
Thread Starter
macrumors member
 
Join Date: Aug 2008
Location: Belgium
Quote:
Originally Posted by larswik View Post
Mvkoe - If you are on Chapter 10 of that book you should have a good idea of what mutable and immutable are like NSArray and NSMutableArray. I would slow down and even start over in the book and really get it. dejo mentioned that you should understand what you are reading before you move on, and it is a good idea.

When I was learning I did the same thing you are doing now and reading your posts sounds familiar. If you treat programming like a race you will lose. It sounds like you are reading every chapter and before you understand the material you are moving on and skipping over what you don't understand.

Your probably copying and pasting lots of code from the internet to Frankenstein your program together. If you are truly coming from a Java background then the cross over should not be that hard. Java deals with mutable and immutable object too.

I would go back to square one and really understand every chapter by writing lots of small programs that cover the material in that chapter. That is what was recommended to me when I started but I thought that knew better and soon I was asking for help like you are now because I did not get it.

My 2 cents if you want to be a good programmer, which I hope to be some day too.
Thanks for the comment, but the code that i'm writing is with help of the book, and with trying to understand how things work, i don't really copy code from the internet without understanding what it really does.

The only problem is that I need to get deeper in immutable and mutable things, and trying to understand the thing of "copy".

In my code i'm always trying to improve things so that it's clean.

Quote:
Originally Posted by PhoneyDeveloper View Post
Hoist by his own petard.

What do you think this does?

Code:
_myMutableArray = [[[NSMutableArray alloc] init] copy];
What is the class of _myMutableArray?

When you're stopped at a breakpoint move the slider at the bottom of the pane all the way to the right so you can see the full stack trace.
It allocates an piece of memory for the NSMutableArray, that's a class of NSArray, then Initialize it. And then the copy i don't know?
Mvkoe is offline   0 Reply With Quote
Old Jan 6, 2013, 08:38 AM   #20
ChOas
macrumors regular
 
Join Date: Nov 2006
Location: The Netherlands
Quote:
Originally Posted by Mvkoe View Post

It allocates an piece of memory for the NSMutableArray, that's a class of NSArray, then Initialize it. And then the copy i don't know?
(I'll just go Dutch here so it might make more sense to Mvkoe)

Wat je doet is: Je roept een nieuw object tot leven van type NSMutableArray. Daarna stuur je init naar dat object. Niets aan de hand.

Maar wat je aan _myMutableArray geeft is een KOPIE van dat object. Dus opeens bestaan er 2! Een waar _myMutableArray naar wijst en 1 waar eeeh... niets meer naar wijst. Dat is een memory leak.

Als je 'strong' gebruikt is dat ongeveer gelijk aan het oude 'retain' in Obj-C. Je neemt eigenlijk het eigenaar zijn op je. Wat er dan gebeurt is: Maak een NSMutableArray initialiseer, en RETAIN. Dat betekent dat de ontvangende parameter (_myMutableArray) voor een gedeelte eigenaar wordt van dat object. Er is geen kopie meer, er is alleen bekend dat er MINSTENS 1 echte eigenaar van is. Zodra je die 'copy' doet is er alleen een eigenaar van het gekopieerde object. Aangezien er geen eigenaar was van het origineel blijft deze 'rondzweven' in het geheugen.
ChOas is offline   0 Reply With Quote
Old Jan 6, 2013, 09:00 AM   #21
Mvkoe
Thread Starter
macrumors member
 
Join Date: Aug 2008
Location: Belgium
Quote:
Originally Posted by ChOas View Post
(I'll just go Dutch here so it might make more sense to Mvkoe)

Wat je doet is: Je roept een nieuw object tot leven van type NSMutableArray. Daarna stuur je init naar dat object. Niets aan de hand.

Maar wat je aan _myMutableArray geeft is een KOPIE van dat object. Dus opeens bestaan er 2! Een waar _myMutableArray naar wijst en 1 waar eeeh... niets meer naar wijst. Dat is een memory leak.

Als je 'strong' gebruikt is dat ongeveer gelijk aan het oude 'retain' in Obj-C. Je neemt eigenlijk het eigenaar zijn op je. Wat er dan gebeurt is: Maak een NSMutableArray initialiseer, en RETAIN. Dat betekent dat de ontvangende parameter (_myMutableArray) voor een gedeelte eigenaar wordt van dat object. Er is geen kopie meer, er is alleen bekend dat er MINSTENS 1 echte eigenaar van is. Zodra je die 'copy' doet is er alleen een eigenaar van het gekopieerde object. Aangezien er geen eigenaar was van het origineel blijft deze 'rondzweven' in het geheugen.
Bedankt! Dat is mooi uitgelegd, hier ben ik opeens veel meer mij dat ze in een boek zouden uitleggen met allemaal moeilijke termen in het Engels!
--
I'll just start reading some basic Objective-C books, for getting really then hang of these things!
Mvkoe is offline   0 Reply With Quote
Old Jan 6, 2013, 02:01 PM   #22
PhoneyDeveloper
macrumors 68020
 
PhoneyDeveloper's Avatar
 
Join Date: Sep 2008
Never had anyone go Dutch on me before.

This issue is a somewhat subtle issue that I wouldn't expect a beginner to figure out. The rules for when to make a @property copy or strong are a little complicated. The simple rule is "Never mark a @property as "copy" for a mutable type."

If you change your @property for the NSMutableArray to be "strong" and not "copy" things should work the way you expect.

The copy method returns an immutable object. mutableCopy returns a mutable object but there is no "mutable copy" adornment for @properties.

Using "copy" protects your code against setting a mutable object when you want an immutable object. But there is no need to have this kind of protection when your object type is mutable.
PhoneyDeveloper is offline   0 Reply With Quote
Old Jan 7, 2013, 11:47 AM   #23
Mvkoe
Thread Starter
macrumors member
 
Join Date: Aug 2008
Location: Belgium
Thanks for all the help people! I'm getting there, made a singleton. I can code the things I want without copy pasting code from the internet!

I'm pretty happy for now!
Mvkoe is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -5. The time now is 07:40 AM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC