I need to pre-populate and save an array in NSUserDefaults so that downstream methods can read and write to ten values stored there. I've constructed this workable solution, but is there a better way of doing this?
Any insight is appreciated!
lq
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *myArray = [[NSMutableArray alloc] init];
// Set the array with ten Zero Value placeholders
for (NSUInteger i = 0; i < 10; ++i) {
[myArray addObject:[NSNumber numberWithInt:0]];
}
[userDefaults setObject:myArray forKey:#"someKeyName"];
[myArray release];
Later methods call this array like this:
- (void)doSomethingUseful {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *someUsefulArray = [[NSMutableArray alloc] initWithArray:[userDefaults objectForKey:#"someKeyName"]];
// read some values, write some values: int someInt = [someUsefulArray objectAtIndex:3]; // etc.
// store array values back to NSUserDefaults . . .
// IS THERE A WAY TO READ AND WRITE DIRECTLY TO INDEX 3 of the NSUserDefaults array instead???
[someUsefulArray release]
}
I've actually done the same thing in a shipping application. Sure, it doesn't feel elegant, but it does the job.
The only more elegant, and more convoluted, solution would be to use a data-driven approach:
Have a .plist file containing what you consider to be your default settings.
If the program detects that the user defaults is empty, it will load this default plist, and commit it to NSUserDefaults.
Using this method your code is not responsible for building the objects. However, if you are trying to accomplish a schema-upgrade, you're going to need to go back to the code.
Related
I know there are many ways for storing data like property list,archiving etc..but other than that is there any other way for storing very small amount of data,which is common to different view controllers(like a common class for storing all the data)?.
Try this
NSUserDefaults
when you want to save small amounts of data such as High Scores, Login Information, and program state.
saving
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// saving an NSString
[prefs setObject:#"TextToSave" forKey:#"keyToLookupString"];
// saving an NSInteger
[prefs setInteger:42 forKey:#"integerKey"];
// saving a Double
[prefs setDouble:3.1415 forKey:#"doubleKey"];
// saving a Float
[prefs setFloat:1.2345678 forKey:#"floatKey"];
[prefs synchronize];
Retrieving
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// getting an NSString
NSString *myString = [prefs stringForKey:#"keyToLookupString"];
// getting an NSInteger
NSInteger myInt = [prefs integerForKey:#"integerKey"];
// getting an Float
float myFloat = [prefs floatForKey:#"floatKey"];
We can do it by creating a singleton class and shared instance
Yes, you can define the required fields in form of an array. Now make sure that the form will provide you an identity and there is some validation through session etc. A a hook to your controller to sense the form submission every time with a particular flag (hidden). So the tablename and CRUD instruction will be provided to this function and every common CRUD functionality will be handled by this single function. By defining the required fields will let you ignore the extra ones like input buttons and many hidden fields.
use NSUserDefault to store values.
Yes you can declare in forms of NSMutableArray or NSMutableDictionary and access it any Viewcontrollers. You need to create a file as NSObject class and in
.h
+(NSMutableDictionary *)ImageCollection;
in .m file
+(NSMutableDictionary *)ImageCollection
{
static NSMutableDictionary *thestring =nil;
#synchronized([Global class]) // in a single threaded app you can omit the sync block
{
if (thestring ==nil) {
thestring=[[NSMutableDictionary alloc]init];
}
}
return thestring;
}
In any View Controllers include that NSObject class file
[[Global ImageCollection]setObject:#"Sample" forKey:#"Dictionary"]; //just example you can save string,image,array anything as you like
Hope this helps .. !!!
Use shared memory, to store and share common data between views.
How can I pass a "MutableArray with full of Objects" to another class by using NSUserDefaults? I know how to pass "MutableArray"s but this does not work!
So;
I have a MutableArray; 'myCityObjects', and I populate it with objects; 'cities'
In each 'cities' object there are properties like cityName, cityLocation etc...
[myCityObjects addObject:cities];
Now, what I want to do is to pass this MutableArray (filled with objects) to another class by using 'NSUserDefaults';
[[NSUserDefaults standardUserDefaults] setObject: myCityObjects forKey:#"MCO"];
And in the other class,
NSMutableArray *getMyCityObjects = [[NSArray alloc] init];
getMyCityObjects = [[NSUserDefaults standardUserDefaults] mutableArrayValueForKey:#"MCO"];
But it doesn't work! I cannot get myCityObjects in the other class, "getMyCityObjects" is empty. How can I fix that?
Thanks,
E.
NSUserDefaults always returns immutable objects, even if the original object was mutable.
In your first View, You can save value in NSUserDefaults like this:
NSMutableArray *arr= [NSMutableArray arrayWithObjects:#"asd",#"dsa",nil];
[[NSUserDefaults standardUserDefaults] setObject:arr forKey:#"MCO"];
After this in another view, you can retrieve value from NSUserDefaults in this way.
NSMutableArray *abc = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"MCO"]];
Your array is nil because the objects in it (your custom objects) can't be serialised.
Please take a look at the NSCoding protocol. Objects you want to serialise (eg for writing to NSUserDefaults) must implement the methods -encodeWithCoder: and -initWithCoder.
I'm sure you'll find how this is rather easily done searching for the terms I gave you...
I have run into this problem before. The problem with the NSUserDefaults is that it can only contain strings, numbers, and booleans, and arrays or dictionaries of those types of values. My solution is to get around that by storing all the properties in NSDictionaries.
Create two class functions on your "cities" class (I'm calling it CityClass):
+(NSDictionary *)dictionaryFromCity:(CityClass *)myCity {
NSDictionary *returnDict = #{#"keyForIntProperty" : myCity.intProperty, #"keyForFloatProperty" : myCity.floatProperty, #"keyForNSStringProperty", myCity.NSStringProperty"};
return returnDict;
}
+(CityClass *)cityFromDictionary:(NSDictionary *)myDict {
CityClass *returnCity = [[CityClass alloc] init];
returnCity.intProperty = [[myDict objectForKey:#"keyForIntProperty"] intValue];
returnCity.floatProperty = [[myDict objectForKey:#"keyForFloatProperty"] floatValue];
returnCity.NSStringProperty = [myDict objectForKey:#"keyForNSStringProperty"];
//any other setup for the CityClass
return returnCity;
}
Now you can store and retrieve your objects without a problem using the new functions:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//store a CityClass object
NSDictionary *storageDict = [CityClass dictionaryFromCity:cityToStore];
[defaults setObject:storageDict forKey:#"keyForCity"];
//retrieve a CityClass object
NSDictionary *retrieveDict = [defaults objectForKey:#"keyForCity"];
CityClass *retrievedCity = [CityClass cityFromDictionary:retrieveDict];
What you can do here is create a Constructor in your other class for e.g.
-(void)initWithArrayOfObject:(NSMutableArray *)arr_OfObjects;
{
arr_SecondClassArrayOfObjects = [[NSMutableArray alloc]initWithArray:arr_OfObjects];
}
From your first class send this array as :
[objOfSecondClass initWithArrayOfObject: myCityObjects];
In my application, I am using a login form to enter into the application, also using NSUserDefaults to store user preferences, for example:
[storeData setObject:self.loginField.text forKey:#"USEREMAIL"];
[storeData setObject:self.PasswordField.text forKey:#"PASSWORD"];
Like I stored, if a new user logs in the NSUserDefaults stored value will be changed. But I want both preferences (ex:new userid and old userid as well as password). So please explain how to store multiple values for same key?
One way to solve this would be to store a NSDictionary with UserIDs as keys and the passwords as values.
Another option is to use Keychain as it specifically designed for this kind of thing and is also more secure.
Create a Global NSMutableArray and add above details in NSDictionary Objects and Store all Objects in array.This way you will have all user objects.You can get it whenever you want.
first of all create global array with AppDelegate class, for example..
userDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingtblArrayForSearch = [userDefaults objectForKey:#"arrScheduleDates"];
if (dataRepresentingtblArrayForSearch != nil) {
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingtblArrayForSearch];
if (oldSavedArray != nil)
arrScheduleDates = [[NSMutableArray alloc] initWithArray:oldSavedArray];
else
arrScheduleDates = [[NSMutableArray alloc] init];
} else {
arrScheduleDates = [[NSMutableArray alloc] init];
}
[arrScheduleDates retain];
after that when you want to store the new record then get all record from arrScheduleDates array and after that add the new record and after that store like whole array like above..
i hope you understand and its helpful for you...
:)
The absolute easiest way to meet your requirements is to use the user's email address (assuming they're all unique) as the storage key for your dictionary, and the password as the value.
If you need to store more than the password, then the value of the key would be another dictionary with keys and values for the user.
An example of the simple case would look similar to :
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSDictionary *storedUsers = [userDefaults objectForKey:#"userData"];
if (nil == storedUsers) storedUsers = [NSDictionary dictionary];
NSMutableDictionary *mutableStoredUsers = [NSMutableDictionary dictionaryWithDictionary:storedUsers];
NSString *userPassword = [self.PasswordField.text copy]; //add autorelease if you aren't using ARC
NSString *userEmail = [self.loginField.text copy]; //add autorelease if you aren't using ARC
if (nil != userEmail)
{
[mutableStoredUsers setObject:userPassword forKey:userEmail];
}
[userDefaults setObject:[NSDictionary dictionaryWithDictionary:mutableStoredUsers] forKey:#"userData"];
[userDefaults synchronize];
first download and import files of given link
https://github.com/ldandersen/scifihifi-iphone/tree/master/security
then where u want to store user preferences write this code
[SFHFKeychainUtils storeUsername:loginField.text andPassword:PasswordField.text forServiceName:#"dhaya" updateExisting:YES error:&error];
where u want password write this code
NSString *password = [SFHFKeychainUtils getPasswordForUsername:loginField.text andServiceName:#"dhaya" error:&error];
NSLog(#"passwordpassword %#",password);
this will working great....
I am new to iOS development and could not find a way to solve this problem:
I have an app that has two views: one where the user enters some information (say a string), and another view where there is a tableview that includes all the strings that were ever entered (like a history view).
What I am trying to find is a good way to store the input string, then load it into the table view data source once the user switches to the history. I tried to use NSUserdefault but with not much success. Just getting messed up with the data structures, etc.
Here is what I am doing on the main view (where the user enters the input string):
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *arr1 = [[NSMutableArray alloc] init];
arr1 = [defaults arrayForKey:#"historyNames"];
[arr1 addObject:string];
[defaults setObject:arr1 forKey:#"historyNames"];
From some reason I get a warning where I read to arr1, and honestly, I doubt that should work anyway.
Can anyone suggest how I could modify this to work properly and achieve what I am looking for?
Thanks.
[defaults arrayForKey:#"historyNames"];
Will return nil if you never initialized and saved an array for that key in NSUSerDefaults.
If you initialize and array and set it once (look up how to initialize default values for NSUserDefaults), it will return a proper array.
Then you can just do
NSMutableArray *arr1 = [NSMutableArray arrayWithArray:[[defaults arrayForKey#"historyNames"]];
Depending on how many elements this array will have, you may be better off using Core Data. Using user defaults is not very efficient for many/large values, just for small settings and things like that.
When your application starts up, look in user defaults to see if you have an array object already from the last time you used it. If there isn't one, call alloc and init for arr1. (You don't want to call it if you're accessing it from defaults.)
NSMutableArray * arr1;
arr1 = (NSMutableArray *) [defaults objectForKey:#"historyNames"];
if (!arr1) {
arr1 = [[NSMutableArray alloc] initWithCapacity:20];
}
In your main view, just add the input string, and save the defaults.
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject: arr1 forKey: #"historyNames"];
[prefs synchronize];
i need your help,i Am stuck in a simple problem,i done a lot of googling but did not get solution.
I want to store Top 5 scores and with names, i done score by NSUserDefaults but don't know how to store it with names.Please help me.I really need your help.
THANKS...
you can save into user defaults as
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSDictionary* dict = [[NSDictionary alloc] initWithObjectsAndKeys:#"jonny",#"name",#"100",#"score", nil];
NSArray* arr = [[NSArray alloc] initWithObjects:dict, nil];
[defaults setObject:arr forKey:#"list"];
[defaults synchronize];
[dict release];
[arr release];
and read the values as
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSArray* arr = [defaults objectForKey:#"list"];
NSLog(#"%#",[arr objectAtIndex:0]);
this works fine for you, it will be a array of dictionaries.
I recommend you familiarize yourself with basic Objective-C collection classes. You can use an NSDictionary to store objects, and those objects can be other objects. You can use this dictionary in combination with NSUserDefaults to store only what you want to store, after having some logic in your app that analyzes your collection class.
Pick up a good book on Objective-C and study sets, arrays and dictionaries.