Store an array of UIViews in NSUserDefaults - ios

I'm trying to add an array of uiviews to NSDefault but it doesn't seem to be keep the array. Does any one know why? I also tried to store each view in nsvalue before storing it in nsdefault which still didn't work.
NSArray *arr = [[NSArray alloc] initWithObjects:[NSValue valueWithNonretainedObject:myView], nil]];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:arr forKey:#"myKey"];
NSArray *resultArray = [defaults objectForKey:#"myKey"];
and resultArray is nil!
Thanks
the reason why I'm trying to do this is because these are the header views of my uitableview. Since it takes time to create them I wanted to create them only once and store them for future access.

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.
If you want to put a UIView (why?) in NSUserDefaults, you need to archive it first into an NSData object.
But you need to ask yourself why you want to put a view in NSUserDefaults. You should only be putting bits of data in NSUserDefaults. Views display data. It's easy to redisplay a view once you have the data back. Consider just putting some needed data in NSUserDefaults.

Are you sure you want to do that? It is definitely better to store an array of models to the data base or some file and recreate views from them when needed.

A ha! You are not the first person to face this issue. I've not had this type of issue myself but, in the link below, is a blog with code that allows you to cache and re-use your views. Then you would only need to re-create the views when you launch. Example code:
Cache UIViews for re-use in tableview

Related

Directly add to array in defaults

Is it okay to call this?
[[[NSUserDefaults standardUserDefaults] objectForKey:#"searchEnginesOrder"] addObject:#"eBay"];
I have a UITableView whose cells I want to load directly from the defaults, and I also want to modify those defaults. I'm wondering if the above line actually has any effect (when I NSLog the default's array searchEngineOrder it's null, I'm wondering if it's because the above code isn't actually adding to the defaults.
Generally speaking, that line of code would crash. User defaults returns immutable objects so calling addObject: will throw an exception.
You also shouldn't rely on changes made to returned objects being backed into the data store - this isn't user defaults specific, it goes for any API which doesn't document it as supported.
You should be separating your logic between your working data and your stored data with defined modifications and save points. Ensure that you mutable copy the data you extract from user defaults. You should also use registerDefaults: to setup initial values so you don't need to check for existence.
NSUserDefaults returns immutable objects. You have to create mutable copies in order to edit the values.
NSMutableDictionary *subSettings;
subSettings = [[[NSUserDefaults standardUserDefaults]
objectForKey:YOUR_SUBMAP_KEY] mutableCopy];
[subSettings setObject:YOUR_NEW_VALUE forKey:YOUR_VALUE_KEY];
[[NSUserDefaults standardUserDefaults]
setObject:subSettings forKey:YOUR_SUBMAP_KEY];
[subSettings release];

NsmutableArray don't succeded to save at close of app

Hello I can not save locally where I have to save an array of strings, I add that this array must be saved when closing the application for iOS and the reopening needs to be recharged, I found thousands of guides online but none are very specific, someone says use NSUserDefaults others say to use NSCoding but in both cases i can not recharge these data can anyone help me?
To Save SMALL data - NSUserDefaults, NSCoding as suggested by other people or saving in plist also or else create a file in document directory and write the contents of array in that file.
LARGE Data- Save it in database using either sqlite or core data.
Choice depends on the requirement of the application and since you have not given the details of the data like maximum number of strings in the array, everyone can suggest you instead of telling a solution. Hope it helps :)
You can use NSUserDefaults:
[[NSUserDefaults standardUserDefaults] setObject:yourMutableArray forKey:#"Key"];
To get the value from NSMutableArray:
NSMutableArray *array = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"Key"]];
Hope this is helpful.

Mutable Objects inside NSUserDefaults

I created a simple database and put in NSUserDefaults. My database is NSMutableArray which has dictionaries and arrays inside in it. When I create NSMutableArray from NSUSerDefaults I can't add any objects to my mutable objects inside my NSMutableArray. Here is my code:
NSMutableArray *arrayOne = [NSMutableArray arrayWithContentsOfFile:[self createEditableCopyOfIfNeededWithFileName:#"Form.plist"]];
NSUserDefaults *ayarlar = [NSUserDefaults standardUserDefaults];
[ayarlar setObject:arrayOne forKey:#"form"];
NSMutableArray *arrayTwo = [NSMutableArray arrayWithArray:[[ayarlar objectForKey:#"form"] mutableCopy]];
[[[arrayTwo objectAtIndex:0] objectForKey:#"itemlar"] addObject:#"hop"];
And here is the error:
'NSInternalInconsistencyException', reason: '-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'
How can I make this work? Thank you everyone.
NSUserDefaults is not the right place to store your data. First of all it should only be used for very small amounts of data, such as settings. And secondly it always returns immutable objects, even if you set mutable ones. Making a mutable copy of your first array doesn’t help because only the array will be mutable. Everything that is inside that array isn’t touched by the mutableCopy method and stay immutable.
You should use the NSPropertyListSerialization class to read and write your data from a file. On reading you can pass options controlling the mutability of the read objects. There you will want to pass NSPropertyListMutableContainers or NSPropertyListMutableContainersAndLeaves.
With the first all your containers (arrays and dictionaries that is) will be mutable. With the latter also the leaves (that is NSString and NSData objects) will be mutable.
Depending on how big your data set can get you probably should use a real database or Core Data instead.
NSUserDefaults never returns mutable objects.
Your code is performing every way of creating a mutable array you can think of (i.e. you're creating a mutable copy of something you just created a mutable copy of), but, you're only dealing with the root container item - not the inner / leaf items. So, when you do objectForKey:#"itemlar"] on your mutable array, you're getting an immutable object back.
To make it work, you'll need to write your own method that iterates and recurses through the array creating mutable copies at all levels.
Alternatively, you could look at a 3rd party option like this which digs under the hood of NSUserDefaults to generate mutable containers.
NSUserDefaults, and property lists in general, do not record mutability. When an object is re-created from the file it can be constructed either as a mutable or immutable object (for types which have the option, such as arrays). Unfortunately NSUserDefaults doesn't give you an API call to obtain an immutable object directly.
Two options you have are (a) create a mutable copy of the object returned by NSUserDefaults or (b) store the object yourself as a property list in a separate file - that way you can read it back as mutable directly.
For (b) read Apple's docs - it shows how mutability is handled.
You can directly do by using method insertObject.
In place of
[[[arrayTwo objectAtIndex:0] objectForKey:#"itemlar"] addObject:#"hop"];
use this,
[arrayTwo insertObject:#"hop" atIndex:0];
This will work for as i have tested it's also working finr after that you can make it as immutable object as NSARRAY and save it to NSUSERDEFAULTS.

Can NSUserDefaults hold a NSArray with custom objects?

The title pretty much explains it. Do I need to serialize the objects first, or is it possible?
You have to code/decode the objects in your object (which is in your array) with and archive the array to NSData.
Just add
<NSCoding>
to the Class of your Objects (in your array) and follow the warnings of your compiler :D
Then archive your array like this:
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:yourArray];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:data forKey:#"yourKey"];
NSArray *array= [NSKeyedUnarchiver unarchiveObjectWithData:[defaults objectForKey:#"yourKey"];
Check this out http://soff.es/archiving-objective-c-objects-with-nscoding
You need to serialize it.
From apple documentation 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.
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html
Yes you can do it.
Check for your answer here:
How to set an NSArray in NSUserDefaults?
yes, it is possible,just you have to take care of NULL values while storing & retrieving it,

Best way to save data to iOS?

In my application (iOS 5) I want to save data - I want to save debts.
So its:
plus or minus money
the amount of money
and the name who has the debts (or the name where you have the debts)
But I don't how to save the data (NSUserdefaults,Core data, SQLLite)
Maybe you can tell me the best way to save them?
The easiest way to store small amount of data on your device is to use NSUserDefaults. But only property lists could be saved in this way. A property list is a combination of objects of 6 types, NSNumber, NSString, NSArray, NSDictionary, NSDate, NSData.
In your case it's easy to do. For example, to save a new debt record you can use following method:
#define DEBTS_LIST_KEY #"listOfAllDebts"
#define DEBTOR_NAME_KEY #"debtorName"
#define DEBT_AMOUNT_KEY #"amountOfDebt"
-(void) saveDebt:(CGFloat) debtAmount forName:(NSString *) debtorName
{
// pointer to standart user defaults
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
// the mutalbe array of all debts
NSMutableArray * alldebtRecords = [[defaults objectForKey:DEBTS_LIST_KEY] mutableCopy];
// create new record
// to save CGFloat you need to wrap it into NSNumber
NSNumber * amount = [NSNumber numberWithFloat:debtAmount];
NSDictionary * newRecord = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:amount,debtorName, nil] forKeys:[NSArray arrayWithObjects:DEBT_AMOUNT_KEY, DEBTOR_NAME_KEY, nil]];
[alldebtRecords addObject:newRecord];
[defaults setObject:alldebtRecords forKey:DEBTS_LIST_KEY];
// do not forget to save changes
[defaults synchronize];
}
To readList of debts you have read something similar.
But I recommend you to use core data. It's more flexible and you won't have to write all this code to manage your data (to edit existed records, or to delete them). You will be able to extend your model much easier, for example, when you want to save the date of the debt. This is the link to a good tutorial
If the quantity of records is user-defined, and will grow with app use, I suggest Core Data, which can be backed by SQLite. If you are working in a modern Xcode (i.e. Xcode 4), creating models is easy and graphical. If you have ever worked with ORM frameworks before, the interface for querying, etc. should be easy to grasp.
Search around for some tutorials, but be specific about finding tutorials that match your version of Xcode, as Core Data development has been changing a lot lately.
Good and easy way is to create your own objects and serialize them using NSCodying and NSCopying
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSCopying_Protocol/Reference/Reference.html
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSCoding_Protocol/Reference/Reference.html

Resources