Using PLists for Persistence on iPhone - iphone

Simple question about property lists within an iphone app. I know you can read data in from a plist, but is there a way to write user-inputted data to a plist? If so, how? It's easy to find tutorials on reading information from plists, but I'm having trouble finding resources on writing to plists.

This is how I write data items to a plist:
[myPlistFile setInteger: myInt forKey: #"someKey"];
Of course, you can change setInteger with setBool, etc for different types.
Hope this helps!
--
Edit:
If your .plist was a member of an important class or similar...
Header of myClass:
NSUserDefaults* myPreferences;
#property (nonatomic, retain) NSUserDefaults* myPreferences;
.m of myClass:
self.myPreferences = [NSUserDefaults standardUserDefaults]; // load our preferences
[[NSUserDefaults standardUserDefaults] registerDefaults: [NSDictionary dictionaryWithContentsOfFile: [[NSBundle mainBundle]pathForResource: #"nameOfFile" ofType: #"plist"]]]; // now load the custom .plist file

In the docs for both NSArray and NSDictionary it shows they each have an instance method:
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag
For NSDictionary it describes this method as
Writes a property list representation of the contents of the dictionary to a given path.
For NSArray it says this in the discussion
This method recursively validates that all the contained objects are property list objects before writing out the file, and returns NO if all the objects are not property list objects, since the resultant file would not be a valid property list.
So essentially both of these will write plist's if the items that they contain can be used in plists e.g. Array, Dictionary, Boolean, Data, Date, Number and String

Related

Add String to an Array with Objects

What I need to do is transfer Text from a text field into an array. here is what I am doing for getting the text:NSString *string = [NSString stringWithFormat#"%#", textfield.text];
Now how can I add this string to my array without loosing all of the objects already in the array?
You need to use NSMutableArray instead of a NSArray.
You will find a very useful method
- (void)addObject:(id)anObject
which
Inserts a given object at the end of the array.
A simple use of NSMutableArray
NSMutableArray *arMu = [[NSMutableArray alloc] initWithCapacity:10];
NSString *s = #"Some string";
[arMy addObject:s];
Also if you have a #property define for the IBOutlet I would do this instead
NSString *string = self.textfield.text;
Documentation is always a good place to have answers
writeToFile:atomically:
Writes the contents of the array to a file at a given path.
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag
Parameters
path
The path at which to write the contents of the array.
If path contains a tilde (~) character, you must expand it with stringByExpandingTildeInPath before invoking this method.
flag
If YES, the array is written to an auxiliary file, and then the auxiliary file is renamed to path. If NO, the array is written directly to path. The YES option guarantees that path, if it exists at all, won’t be corrupted even if the system should crash during writing.
Return Value
YES if the file is written successfully, otherwise NO.
Discussion
If the array’s contents are all property list objects (NSString, NSData, NSArray, or NSDictionary objects), the file written by this method can be used to initialize a new array with the class method arrayWithContentsOfFile: or the instance method initWithContentsOfFile:. This method recursively validates that all the contained objects are property list objects before writing out the file, and returns NO if all the objects are not property list objects, since the resultant file would not be a valid property list.
Availability
Available in Mac OS X v10.0 and later.
See Also
– initWithContentsOfFile:
Declared In
NSArray.h

How to save a NSMutableDictionary into a file in documents?

I would like to save the content of a NSMutableDictionary object to a file. How do I do this ? I already know how to do this task with a NSDictionary object but I don't know how to convert/copy this NSMutableDictionary to a NSDictionary...unless there's a method to write directly the content of NSMutableDictionary to a file...I stress that the NSMutableDictionary object contains objects of NSDictionary type.
Thx for helping,
Stephane
NSMutableDictionary is a subclass of NSDictionary: you can use it anywhere you'd use NSDictionary. Literally, just pass the object through to the same code you use for NSDictionary right now.
In a more general sense, if you ever actually need to get a truly immutable NSDictionary from an NSMutableDictionary, just call copy on the NSMutableDictionary.
Other approaches include [NSDictionary dictionaryWithDictionary:] or [NSDictionary alloc] initWithDictionary:], which all amount to essentially the same thing.
If you just swing over to the NSDictionary documents. You will see there is a method for saving a dictionary to a file
writeToFile:atomically:
Writes a property list representation of the contents of the dictionary to a given path.
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag
Parameters
path:
The path at which to write the file.
If path contains a tilde (~) character, you must expand it with stringByExpandingTildeInPath before invoking this method.
flag:
A flag that specifies whether the file should be written atomically.
If flag is YES, the dictionary is written to an auxiliary file, and then the auxiliary file is renamed to path. If flag is NO, the dictionary is written directly to path. The YES option guarantees that path, if it exists at all, won’t be corrupted even if the system should crash during writing.
Return Value
YES if the file is written successfully, otherwise NO.
This method recursively validates that all the contained objects are property list objects (instances of NSData, NSDate, NSNumber, NSString, NSArray, or NSDictionary) before writing out the file, and returns NO if all the objects are not property list objects, since the resultant file would not be a valid property list.
If the dictionary’s contents are all property list objects, the file written by this method can be used to initialize a new dictionary with the class method dictionaryWithContentsOfFile: or the instance method initWithContentsOfFile:.
So the piece of code you are looking for is probably something like:
[myDict writeToFile:path atomically:YES]
where myDict is the dictionary you have and path is the path to the location you want to save it to

Saving custom data types

Im making an app similar to apples weather app. My main view has a NSMutableArray of objects to be displayed. This array is managed by the user. I want to be able to save this array so that when the app is relaunched it has the stuff the user selected. The objects stored are "Event" objects which is a custom object type that stores more custom objects that all hold some of the following: NSString, NSNumber, NSUInteger, NSURL. My research has led me to three options, none of which i understand, nor know how to implement: saving to a plist using writeToFile, archiving the data, or saving it to userPrefs.
Does anybody know of a solution to my problem?
Sample data object:
`
#interface Rider : NSObject {
NSString *name;
}
-(Rider *) initWithName:(NSString *) nam;
- (NSString *)description ;
#property (nonatomic, retain) NSString *name;
`
At least two of those three options are reasonable. NSUserDefaults is really meant more for storing application preferences than as an option for storing the bulk of your data, so if you have a lot of data you should look at other possibilities first.
Property lists are easy to read and write, but you're limited to using a handful of standard types: NSString, NSData, NSArray, NSDate, and NSNumber. You can do quite a lot with those types, but since your own Event class is involved using property lists won't be so simple.
Archiving seems like the best plan. All you need to do is to adopt a simple protocol, NSCoding, in your custom classes (and make sure that the other classes that you use, like NSArray, also implement NSCoding). Then, create an instance of NSKeyedArchiver and ask it to archive your object graph. Recreating the object graph later is just as simple: create an NSUnarchiver instance with your file's data and unarchive your objects.
You can read about both archiving and property lists in the Archives and Serializations Programming Guide. Read that document before you go any farther.
There are other options as well -- you can always use the standard C file operations to write directly to a file if you want. It's unlikely that that will be as convenient as archiving, however.
Your question itself has the answer.
Create each of your object as dictionary and finally you will have array of dictionaries.
NSArray and NSDictionary has the methods to write its data to a file (plist is preferred). If you use plist files, it will be easy to read again.

trouble with saving iPhone App variables of different types

As all who usually ask such questions I'm newbie in iPhone SDK programming and I've spend realy a lot of time to find the solution by my self.
So, I need to save a lot of app data of diff datatypes (bool,string,int,float,double,int arrays,double arrays and arrays of pointers) to file. There're many forms with fields, app settings etc. All that I need to save either user quit the app, or it was terminated unexpectedly. User could work with as much forms with fields, as it's possible. File is needed to open project with all filled forms and app sets on other device.
My trouble is that I couldn't find in what way I should wrilte all that data to file. I tried two diff ways. 1st: fill array with form's data, fill NSMutableArray with such arrays for every form. But for NSMutableArray there's a method (void)addObject:(id)anObject, and I didn't find how to get that (id)anObject from every array(or anything else) to add items.
The 2nd I've tried to use: NSMutableData. The same troubles: to fill with my data I need to convert them to Data ((void)appendData:(NSData *)otherData). In both cases objecs of that classes couldn't be filled correctly with my data. And I can't save it to file.
Maybe there's some better solution? Will be very apreciative for any help.
NSNumber is usually the way to go for basic stuff (integers, bools, and doubles/floats/etc). For example:
NSNumber *aBool = [NSNumber numberWithBool:YES];
NSNumber *aFloat = [NSNumber numberWithFloat:1.0f];
NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];
[settings setValue:aBool forKey:#"some_key"];
The strings you can just add to NSUserDefaults because they are already objects (that conform to NSCoder, I believe), and for the NSArrays, just use the writeToFile: method:
NSArray *someArray = [NSArray arrayWithObjects:#"foo",#"bar",#"etc",nil];
[someArray writeToFile:#"filename" atomically:YES];

Serialize an Array of data

I currently write to and read from an array of data, and use the index of each element to achieve something. I need a way to store this array, I looked at the user defaults, but that stores a dictionary, with retieval using keys. I will not know what key was stored.
What is the best was to store ths array of data on the iphone?
Regards
NSKeyedArchiver, a concrete subclass
of NSCoder, provides a way to encode
objects (and scalar values) into an
architecture-independent format that
can be stored in a file.
So you can serialize anything you like to a file:
// need a path
- (NSString*) getPath
{
NSString* path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
return [path stringByAppendingPathComponent:#"someInfo"];
}
// save an array
- (void) save:(NSArray*)array
{
[NSKeyedArchiver archiveRootObject:array toFile:[self getPath]];
}
// get that array back
- (NSArray*) load
{
return [NSKeyedUnarchiver unarchiveObjectWithFile:[self getPath]];
}
You might want to serialize a dictionary of arrays if you have more than one you want to store.
It is possible to store an array in NSUserDefaults. It does however depend on the kind of objects the array holds. NSKeyedArchiver is another good option, as is storing the array as a plist. It could even be that CoreData is the best choice for you. It all depends on the expected size of your data and how you use it. NSKeyedArchiver seems a fair enough middle ground for many situations, but to answer you question more info is needed.