how can i store value in an NSArray using WritetoFile? - iphone

i wana store the index of seleted cell of table using NSArray, can u help me....

You can use user defaults or property list for this.
Example on user defaults. You have a controller class that has access to the index and will load it at startup and write it into plist whenever it's updated:
If you have some kind of controller class then you would put this code into + (void)initialize, it initialises the variable if it does not exists in plist:
+ (void)initialize
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults =
[NSDictionary dictionaryWithObject:[NSNumber numberWithInteger:5]
forKey:#"MyFunnyIndex"];
[defaults registerDefaults:appDefaults];
}
In your -(void)awakeFromNib (I'm assuming you're using some kind of controller class) load your last stored value:
-(void)awakeFromNib
{
int index =
[[NSUserDefaults standardUserDefaults] integerForKey:#"MyFunnyIndex"];
[somethingThatNeedsIndex setIndex:index];
// ...
}
Somewhere where the index is updated (or where you want to write it to plist), let's call it - (void)updateInterface:
- (void)updateInterface
{
[[NSUserDefaults standardUserDefaults]
setObject:[NSNumber numberWithInteger:index]
forKey:#"MyFunnyIndex"];
[[NSUserDefaults standardUserDefaults] synchronize];
}

I don't know if I understand the question correctly, but it sounds like you could use a property list to store this information. Property lists are very easy to use and quite efficient with small amounts of data.
Read the "Property List Programming Guide" for further explanation. There is even a tutorial in there.

Related

Does NSUserDefaults delete keys, that are not needed temporarily?

I'm storing all my data in NSUserDefaults.
Now I'm trying to store some keys with a specific prefix in an Array. Therefore, I first load the UserDefaults in a Dictionary.
NSString *myPrefix = #"prefix";
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *dict = [defaults dictionaryRepresentation];
for (NSString *keyWithPrefix in dict.keyEnumerator) {
if ([keyWithPrefix hasPrefix: myPrefix]) {
[relevantKeys addObject: keyWithPrefix];
}
}
The Problem is: when I print "dict" (which represents UserDefaults). There are some keys missing.
Does NSUserDefaults delete keys, that are not needed temporarily?
Nope it does not, NSUserDefault is a persistance storage,
Please read the following answer it has a very good explanation
How persistent is [NSUserDefaults standardUserDefaults]?
No, but are you calling [NSUserdefaults synchronize] when you are updating them ?
You should probably be using -synchronize method when storing what you want. i,e:
[[NSUserDefaults standardUserDefaults] setValue:someDictionary forKey:#"someKey"];
[[NSUSerDefaults standardUserDefaults] synchronize];

adding an item to at array in NSUserdefault

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];

NSUserDefaults standardUserDefaults setObject: forKey: not working for Multivalue preference

I am trying to do following task
[[NSUserDefaults standardUserDefaults] setObject:#"Dry" forKey:#"vesselType_preference"];
[[NSUserDefaults standardUserDefaults] synchronize];
where my "vesselType_preference" is multivalue attribute, but it is not getting effected. Please help this is working for other type of attribute but not working for multivalue type.
Thanks
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![defaults objectForKey:#"vesselType_preference"])
{
[defaults setObject:#"Dry" forKey:#"vesselType_preference"];
}
[[NSUserDefaults standardUserDefaults] synchronize];
This should work.
NSUserDefaults can only handle objects of NSDictionary, NSData, NSArray, NSString and BOOL. (There might be another in there, not sure) If you need to store a multiple value object like an array or dictionary, I would store your settings there first, then save that to the defaults.
Your code looks fine for storing information to the user defaults. Just make sure you have your object type specified before saving. (id) will not work... or won't work properly.

JSON and Core Data:Should I convert JSON into Core Data?

I'm new to Core Data and I need some help on my project.
I'm developing iPhone app that get JSON (Restaurants info) from server and shows the location on the map and table view, and stores favorite restaurants by pressing "add favorite" button.
For now, I'm just using NSDictionary and its functions to display data on the table and annotations and having favoriteRestaurant entity to store favorite restaurant data.
However, I would like to convert the NSDictionary object into Core Data object (Restaurant), and add "BOOL isFavorite" attribute to it and then delete favoriteRestaurant entity.
Make function that saves the restaurant object that passed and changes its "isFavorite" state, which is triggered by "add Favorite" button.
The favorite table shows only the restaurants that has been saved and isFavorite = YES.
I would like to know if this is right approach to accomplish what I want.
Thank you in advance!
Hi, thank you for fast responses. I forgot to say that I also want to implement MKAnnotation to that class so each annotation pin on the map belongs to unique restaurant object. If I want to do this, should I have another favorite class or Core Data entity, or just save it in the Restaurant table and make isFavorite = YES? Thank you, again!
If you're only concerned about saving the favorites then id go with plist serialization. I do the same thing in multiple apps. Normally I create a Helper class like below.
#import "Favorites.h"
#import "NSArray+Locations.h"
#implementation Favorites
+(void)addFavorite:(Location *)location{
NSMutableArray *remove = [NSMutableArray array];
[location.data enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(#"%#,%#, %#",key,obj,[obj class]);
if([obj isKindOfClass:[NSNull class]])
[remove addObject:key];
}];
[location.data removeObjectsForKeys:remove];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary * favorites = [NSMutableDictionary dictionaryWithDictionary:[defaults objectForKey:FAVORITES]];
if(!favorites)
favorites = [NSMutableDictionary dictionaryWithCapacity:1];
[favorites setObject:location.data forKey:[location getID]];
[defaults setObject:favorites forKey:FAVORITES];
[defaults synchronize];
}
+(void)removeFavorite:(Location *)location{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary * favorites = [NSMutableDictionary dictionaryWithDictionary:[defaults objectForKey:FAVORITES]];
[favorites removeObjectForKey:[location getID]];
[defaults setObject:favorites forKey:FAVORITES];
[defaults synchronize];
}
+(NSArray *)getFavorites{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary * favorites = [defaults objectForKey:FAVORITES];
return [NSArray arrayWithLocations:[favorites allValues]];
}
+(BOOL)isFavorited:(Location *)location{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary * favorites = [defaults objectForKey:FAVORITES];
for(NSString *key in [favorites allKeys])
if([[location getID] isEqualToString:key])
return YES;
return NO;
}
#end
In this case the Location object is just a wrapper around a dictionary to make accessing the fields simpler.
If you want to save all of your data and not just favorites then I would go with core data otherwise a very large plist could give you memory headaches.
I like your approach. In my opinion Core Data is the way to go.
If you get lots of JSON records (say, dozens or hundreds of restaurants) with maybe even more data fields in the future, you could run into memory problems when using an array of NSDictionarys. Remember, a serialized plist can only be retrieved entirely, so if it gets large you will have to keep all the data in memory.
Also, you will very like have a much better performance from the start.
Your BOOL attribute (in Core Data that would be a NSNumber) should work fine for your purpose.

iPhone code to create new NSUserDefaults objects?

I have NSUserDefaults storing a number of string variables for things like name, date of birth, address, etc. What I would like to know is how to write a code that will create a new object for each new user. For example, I have a spinning wheel that shows up immediately after the first time the user runs the app. What I want, is for that wheel to have one single option - "New User". Once that New User fills out a bunch of text fields that I am using NSUserDefaults to save, I want that user to be saved on that spinning wheel so that the next time they open up the app they have the option of returning to all of the variables that they previously put in, or creating a new user so they can input all new variables.
I know how to do everything except write the code to create new users automatically. Potentially, the program should allow for a limitless number of these user objects and then just use something arbitrary like their last name to input into the spinning wheel. I would assume that the code would need to be put somewhere in the following code used to save the NSUserDefaults:
NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
[userData setObject:txtName.text forKey:#"name"];
---EDIT FOR CLARIFICATION ----
I am able to put multiple strings into this 'userData' object already by simply adding more lines like the 2nd line from above. What I want to know is how to add 'user2Data', 'user3Data', 'user4Data', 'usernData'..........to make a potentially limitless amount of user objects to store these variables?
You can add NSArray objects to NSUserDefaults.
NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
NSMutableArray *users = [NSMutableArray mutableArrayWithArray:[userData objectForKey:#"users"];
[users addObject:txtName.text];
[userData setObject:[NSArray arrayWithArray:users] forKey:#"name"];
[userData setObject:txtName.text forKey:#"name"];
If you need more than a single string for user data, you can look at using an NSDictionary object.
All that said, if you're going to be storing a lot of data, you should look at maybe saving .plist files in your app's Library directory.
You could modify the following to meet your needs, to be put into your app delegate:
+ (void) initialize
{
if ([self class] == [MyAppDelegate class]) {
// initialize user defaults dictionary
BOOL isFirstTimeRun = YES;
...
NSMutableDictionary *resourceDict = [NSMutableDictionary dictionary];
[resourceDict setObject:[NSNumber numberWithBool:isFirstTimeRun] forKey:kIsFirstTimeRunKey];
...
[[NSUserDefaults standardUserDefaults] registerDefaults:resourceDict];
}
}
...
- (void) applicationDidFinishLaunching:(UIApplication *)application
{
if ([[[NSUserDefaults standardUserDefaults] objectForKey:kIsFirstTimeRunKey] boolValue]) {
// you could do first-time-run stuff here, such as initializing
// other data model elements...
}
...
}
...
- (void) applicationWillTerminate:(UIApplication *)application
{
// if we're quitting the app, it must have been run at least once
if ([[[NSUserDefaults standardUserDefaults] objectForKey:kIsFirstTimeRunKey] boolValue])
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:kIsFirstTimeRunKey];
...
}
What you probably want to do is create a property list for each user, and save the list of users in your NSUserDefaults. Once a user has been selected, you can then load the contents of the property list for that specific user and load/store all data in that particular property list. The basics of this approach is to use an NSDictionary* wherever you need to read from the property list and an NSMutableDictionary* whenever you need to both read and write to it. When you first construct the property list, you simply instantiate an NSMutableDictionary. When you want to save it or load it, you can use the NSPropertyListSerialization class in order to save or load the dictionary from/to a property list.