How to save an NSMutableArray containing NSMutableArrays of custom objects in NSUserDefaults - objective-c

I was able to save an NSMutableArray of custom objects to NSUserDefaults by implementing NSCoding in the custom class. However, now I want to save an NSMutableArray of these arrays. The compiler complains when I try to do this. How can this be done?

I found out how to do it. Basically, your transform the array into a data object using NSKeyedArchiver, and that is what you save with NSUserDefaults. Then when you get the data object back, you use NSKeyedUnarchiver to turn it back into an array.

Related

Save and load arrays - Objective c

I am developing an app and needs to save arrays, but I'm not sure how I can do it. Does anyone know how I could save and load arrays in Xcode Objective-c?
Thanks!
That's a very broad question, but here is a very simple answer.
To save your array to file:
[NSKeyedArchiver archiveRootObject:array toFile:fileName];
To load your array from that file:
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:fileName];
These calls depend on the fact that NSArray implements NSCoding (through NSSecureCoding).

saving NSMutuableArray to NSUserDefault gives warning

I have NSMutuableArray of UIImages . when trying to save him to userDefaults, i get warning.
If its an array of strings, its working ok.
//save to memory
NSMutableArray *savedImages=[[NSMutableArray alloc]init];
for(int j=0;j<[selectedButtonsTags count];j++)
[savedImages addObject:[assets objectAtIndex:[[selectedButtonsTags objectAtIndex:j] intValue]]];
[memoryInstance setTempImagesToSend:savedImages]; //here save to NSUserDefault
[savedImages release];
warning :
[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value
Why the userdefault care what objects my array holds ??
From the docs for NSUserDefaults:
The NSUserDefaults class provides convenience methods for accessing common types such as floats, doubles, integers, Booleans, and URLs. A default object must be a property list, that is, an instance of (or for collections a combination of instances of): NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. If you want to store any other type of object, you should typically archive it to create an instance of NSData. For more details, see Preferences and Settings Programming Guide.
You will notice that UIImage is not in the list. You must convert the UIImage to an NSData object first before you can store the image in NSUserDefaults.
However, you should not use NSUserDefaults to store lots of binary data. Instead, write the images to the filesystem. Store them in an appropriate folder within the app's sandbox. You can store the filenames in NSUserDefaults if needed.

NSArrayController + NSTableView : automatically save changes without Core Data

OK, so I'm implementing a classic scenario :
A NSPopupButton with some items in it
When the selected value changes, my itemsArray is updated
The itemsArray is linked to an NSArrayController
Each item in the itemsArray is an NSMutableDictionary (with keys : title,content)
An NSTableView displays the titles of the arrangedObjects (binding)
An NSTextView displays the content of the selected item.
Now, what I want is to automatically save any changes to the itemsArray (or itemsArray's item title/content), but without using Core Data (which I suspect might have been the best way to go about it).
I imagine it's quite a basic question this one, but honestly I've never really like Cocoa's auto-magical way of doing things... so, I need your help...
How should I go about that?
You can write an array to a file very easily:
[yourArray writeToURL:someFileURL atomically:YES];
This will work if all the contents of the array are property list objects (i.e. they are NSNumber, NSString, NSDictionary, NSArray or NSData objects). This is the case in your example.
You can then recreate the array using either the arrayWithContentsOfURL: or initWithContentsOfURL: methods when you load from disk.
If your model object is more complex than just an array, then you should make your model object conform to the NSCoding protocol. This means you need to implement the initWithCoder: and encodeWithCoder: methods. You can then use the NSKeyedArchiver and NSKeyedUnarchiver classes to convert your object to and from an NSData representation that you can write to disk.
You should read the Archives and Serialization Programming Guide for more detailed information.
Another solution might be to add a Shared User Defaults Controller and bind the Controller Content Array from the Array Controller to the Shared User Defaults Controller

Storing custom objects to NSMutableArray, then storing this NSMutableArray to NSUserDefaults

I would like to store some custom objects in an NSMutableArray, then store this NSMutableArray to NSUserDefaults. The custom objects look like this:
#interface myCustomClass:NSObject
{
NSString *string1;
NSString *string2;
NSArray *array;
NSURL *URL;
}
#end
I've checked the development documentations and learned that NSUserDefaults only supports some types such as NSData, NSDate, NSString, NSArray, NSDictionary. I have searched the answer to my question for a while but haven't got a solution. Would anyone please let me know how could I save my custom objects listed above to NSMutableArray then store this array to NSUserDefaults, and how to retrieve this mutable array? Thanks a lot in advance.
Objects that can be cached using NSUserDefaults must be property lists. If you would really like to use NSUserDefaults to cache these, then you must first implement a method that return all attributes necessary to recreate your object. This would mean a property list representation of your object, such as an NSDictionary. Think in terms of serialization/deserialization. For your case you have to ensure that your NSArray ivar in turn contains property lists only. If you can recreate NSURL using an NSString only, then save the NSString instead. You see it is getting complicated!
A much simpler approach would be to implement the NSCoding protocol in your custom class and save/retrieve your object or NSArray of objects using NSKeyedArchiver and NSKeyedUnarchiver. To implement the NSCoding protocol, you must implement only two methods initWithCoder: and encodeWithCoder:

Do I need to use NSKeyedArchiver?

I have an object. It has only two NSStrings as properties.
I created an array to hold several of these objects.
Do I need to use NSKeyedArchiver to save this array to disk, or can I just use NSUserDefaults?
If your object is a custom class, you will need to use NSKeyedArchiver before you put the contents in NSUserDefaults. See here.
You can just use [[NSUserDefaults standardUserDefaults] setObject:myArray forKey:myKey]; for writing and [[NSUserDefaults standardUserDefaults] arrayForKey:myKey]; for reading (there is no setArray:forKey: as it's not needed).
Also, if you got an array that you don't want to store inside NSUserDefaults there's an easy possibility to write and read arrays: -[NSArray writeToFile:atomically:] and +[NSArray arrayWithContentsOfFile:]. There also the same methods for NSDictionary to easily read/write dictionaries. Of course you're always free to use NSKeyed(Un)Archiver as well.