Store temporary data in iOS - ios

I want to store data in iOS for globally, like session data in web. What is the best approach other than sqlite?

You can write basic types like NSNumber, NSString, NSArray, NSDictionary, etc directly into the NSUserDefaults. These will be automatically saved/loaded between app sessions.
NSString* myData = #"someValue";
[[NSUserDefaults standardUserDefaults] setObject:myData forKey:#"myData"];
For more complex data types you can take advantage of NSCoder and the NSCoding protocol to easily make your classes serializable.
The code in the answer here may be helpful.
Save own Class with NSCoder

You need to use NSUSERDefault its very easy to handle.
You can save NSString,NSDictionaray ,NSnumber in NSUserDefault like this..
// Store Array values
NSMutableArray *array = [NSMutableArray array];
[[NSUserDefaults standardUserDefaults] setObject:array forKey:#"array"];
// Stroe String to nsuserDefault
NSString *str=#"ABC";
[[NSUserDefaults standardUserDefaults] setObject:str forKey:#"value"];

You can use NSUserDefaults for that.
For saving data you can use this code
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:#"Dilip" forKey:#"firstName"];
[defaults setObject:#"Manek" forKey:#"lastname"];
[defaults setInteger:24 forKey:#"age"];
[defaults synchronize];
And for retrieving data use this code
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *firstName = [defaults objectForKey:#"firstName"];
NSString *lastName = [defaults objectForKey:#"lastname"];
int age = [defaults integerForKey:#"age"];
NSString *ageString = [NSString stringWithFormat:#"%i",age];
You can also store NSDictionary, NSArray, or NSData as object in NSUserDefault.For more information take a look at this tutorial.
another way to pass data Between viewController is like this.
Suppose we have Two ViewController
-FirstViewController
-SecondViewController
Now if i want to pass a string from First to second ViewController thanfirst create Property of that string in secondViewcontroller
#import <UIKit/UIKit.h>
#interface SecondViewcontroller : UIViewController
#property (strong, nonatomic) NSString *strFromFirst;
#end
Synthesize it in .m file. after that in firstViewController when you push view controller Send string to second Viewcontroller
SecondViewcontroller * vc = [[SecondViewcontroller alloc] initWithNibName:#"SecondViewcontroller" bundle:nil];
// Pass the selected object to the SecondViewcontroller.
fraudluntReportViewController.strFromFirst = #"Dilip";
[self.navigationController pushViewController:vc animated:YES];
This will send the string from FirstViewController to SecondViewController.

Use NSUserDefaults.
NSUserDefaults is great for saving samm data like scores, login information, program state. You dont require database knowledge and its easy to learn and use.
Here is the documentation:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html
Here is a good tutorial:
http://www.icodeblog.com/2008/10/03/iphone-programming-tutorial-savingretrieving-data-using-nsuserdefaults/
Edit:
Although, based on your comment it seems that you just want to pass data between ViewControllers.
One way :
Lets suppose you want to pass NSString myString from ViewControllerA to ViewControllerB.
Then create a property like this in ViewControllerB.
#property (strong, nonatomic) NSString *passedString;// strong if you are using RC, ow retain
In ViewControllerA.m , when you are allocating, initiating ViewControllerB, then
ViewControllerB *viewControllerB = [[ViewControllerB alloc]init];
viewControllerB.passedString = myString;
Another Way: (more of a global variable type way)
You can declare a property in AppDelegate.h
#property (strong, nonatomic) NSString *passedString;
In ViewControllerB, you can create AppDelgate object and access the property:
AppDelegate *app = [[UIApplication sharedApplication]delegate];
NSString *passedString = app.passedString;

If you have limited data to store feel free to use NSUserDefaults.
Apple Reference for NSUserDefaults
for example you need to store some string(say name) in to user defaults.
NSString *name = "Your Name";
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:name forKey:#"name"];
[defaults synchronize];
IMPORTANT here is, once you done with setObject for key, you have to call synchronize method so that these changes get stored in User Defaults
for accessing the same firstName string
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[defaults objectForKey:#"name"];

Related

How to display data in NSMutableDictionary?

language: Objective-C,
I'm new at iOS development so please guide me in a easiest way if you can, i'm saving data into dictionary then NSUserDefaults after that i want to get the data from they NSUserDefaults, I'm working when user clicked in a texfield then text should be stored into dictionary but when i check into Xcode after setting a break points dictionary shows nil. I'm sending screenshots and code please help me.
Thanks
initialization of dictionary in viewDidLoad
save to NSUserDefaults
-(void)textFieldDidEndEditing:(UITextField *)textField {
//we'll use the following method if the TF is out of the table means not in a cell.
if([textField isEqual:self.getNameLabel]){
[nameDateDict setObject:[textField text] forKey:K_NAME];
[self saveToNSUserDefaults];
}
}
Xcode-output
nameDateDict NSMutableDictionary * nil 0x0000000000000000
Sorry the name of texfield is getNameLabel, I'll edit it later so please don't confuse after reading the name.
Even that i've checked this code is working
[timeDict setObject:#"Hello" forKey:#"Greetings"];
[timeDict setObject:#"Bye" forKey:#"B_Key"];
[timeDict setObject:#"what?" forKey:#"W_Key"];
[[NSUserDefaults standardUserDefaults] setObject:timeDict forKey:#"Greetings"];
[[NSUserDefaults standardUserDefaults] setObject:timeDict forKey:#"B_Key"];
[[NSUserDefaults standardUserDefaults] setObject:timeDict forKey:#"W_Key"];
[[NSUserDefaults standardUserDefaults] synchronize];
timeDict = [[NSUserDefaults standardUserDefaults] objectForKey:#"Greetings"];
timeDict = [[NSUserDefaults standardUserDefaults] objectForKey:#"B_Key"];
timeDict = [[NSUserDefaults standardUserDefaults] objectForKey:#"W_Key"];
A couple of things are going on here. First, you have a scope problem, in that your create a local dictionary object in viewDidLoad, which you can't access later. It looks as though you'll want to have an NSMutableDictionary property available for the class, which should be designated either in the header file or interface extension in the implementation file (depending on your use of this dictionary in your project):
#property (nonatomic, strong) NSMutableDictionary *nameDateDictionary;
Second, you aren't correctly initializing or accessing your dictionary and it's objects. So, (using some literal syntax shortcuts) your viewDidLoad and saveToNSUserDefaults methods:
- (void)viewDidLoad
{
[super viewDidLoad];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *name = [defaults objectForKey:K_NAME];
NSDate *startDate = [defaults objectForKey:K_START_DATE];
NSDate *endDate = [defaults objectForKey:K_END_DATE];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithDictionary:#{K_NAME: name,
K_START_DATE: startDate,
K_END_DATE: endDate}];
self.nameDateDictionary = dict;
}
- (void)saveToNSUserDefaults
{
NSMutableDictionary *dict = self.nameDateDictionary;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:dict[K_NAME] forKey:K_NAME];
[defaults setObject:dict[K_START_DATE] forKey:K_START_DATE];
[defaults setObject:dict[K_END_DATE] forKey:K_END_DATE];
[defaults synchronize];
}
- (BOOL)textFieldShouldReturn:(UITextField*)theTextField {
[theTextField resignFirstResponder];
return YES;
}
-(void) textFieldDidEndEditing:(UITextField *)textField {
[self saveToNSUserDefaults:#{#"keyName":textField.text}];
}
-(void)saveToNSUserDefaults:(NSDictionary *)dict{
[[NSUserDefaults standardUserDefaults] setObject:dict forKey:#"myDictionary"];
}
-(void *)retrieveFromNSUserDefaults{
NSDictionary *tempDict=[[NSDictionary alloc] initWithDictionary:[[NSUserDefaults standardUserDefaults] objectForKey:#"myDictionary"]];
NSlog(#"TextField Value: %#",[tempDict objectForKey:#"keyName"]);
}
The way you are storing the dictionary was not correct. Please go through the https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/index.html for more about how to use them.
Everyone came from a beginner's stage but try not to skip the basics.
As on your screenshots you are storing dictionary values in a wrong way, you store each time the whole dictionary to each NSUserDefaults key. It schoul be like that:
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:#"value" forKey:#"key"];
[[NSUserDefaults standardUserDefaults] setObject:[dict objectForKey:#"key"] forKey:#"key"];
To get back a value from NSUserDefaults to dictionary:
[dict setObject:[[NSUserDefaults standardUserDefaults] objectForKey:#"key"] forKey:#"key"];

Adding new values to existing keys of nsuserdefault using nsmutablearray

I am finding some problem while saving and retrieving data using nsuserdefaults.
What i want to do- iam accepting name and number from user from viewcontroller and saving it using nsuserdefault. when i click on save button i want to retrieve all the values from nsuserdefault and display it on tableview. now when i save the new data i want this data to get added to the existing data of nsuserdefault. can anyone help me with saving and retrieving nsuserdefault data.
----------MyCode---------------
nsuserdefaults *objdefault =[nsuserdefaults standarduserdefaults];
nameArray = [objdefault objectforkey:#"Name"];
[newNameArray addobject:txtName.text];
[nameArray addobject:newNameArray];
[objdefault setobject:nameArray forkey:#"Name"];
[objdefault synchronize];
all this saves and accepts null value
Please help. and thank you in advance
Use these methods to add name to NSUserDefaultsand get from NSUserDefaults
To add the name to NSUserDefaults call [self addNameToUserDefaults:#"abc"];
-(void)addNameToUserDefaults:(NSString *)name number:(NSString*)number{
NSUserDefaults *objdefault =[NSUserDefaults standardUserDefaults];
NSMutableArray *nameArray = [[objdefault objectForKey:#"NameAndNumber"] mutableCopy];
if(!nameArray)
nameArray = [#[] mutableCopy];
[nameArray addObject:#{#"name":name,#"number":number}];
[objdefault setObject:nameArray forKey:#"NameAndNumber"];
[objdefault synchronize];
}
To get all names from NSUserDefaults call NSMutableArray *names = [self getAllNames];
-(NSMutableArray *)getAllNames{
NSUserDefaults *objdefault =[NSUserDefaults standardUserDefaults];
return [[objdefault objectForKey:#"NameAndNumber"] mutableCopy];
}
It's not possible to add values for same in NSUSerDefaults. it will show you last value only. You should go for Core data or Sqlite. Still if you are not comfortable with that you can use plist to achieve this functionality.
This is what I have done in my project. You have to use NSMutableDictionary to add more value
- (void)addUserLocation:(NSString *)username location:(NSMutableDictionary *)location
{
NSString *currentUserKey = [NSString stringWithFormat:#"%#_%#", UserDefaultsKeyLocationData, username, nil];
NSMutableArray *oldData = [[NSMutableArray alloc]init];
if ([self loadUserLocation:username] != nil) {
oldData = [self loadUserLocation:username];
}
if (![oldData containsObject:location]) {
[oldData addObject:location];
}
[[NSUserDefaults standardUserDefaults] setObject:oldData forKey:currentUserKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (NSMutableDictionary *)loadUserLocation:(NSString *)username
{
NSString *currentUserKey = [NSString stringWithFormat:#"%#_%#", UserDefaultsKeyLocationData, username, nil];
return [[[NSUserDefaults standardUserDefaults] objectForKey:currentUserKey] mutableCopy];
}
If you want get all data. Please call loadUserLocation in your code

Best way to store iPhone data (custom NSObject)

I have an NSMutableArray in which I store objects called "address". An address is an NSObject with 4-5 properties (NSStrings). The NSMutableArray shall contain a maximum of 15 address object.
What is the best way to store that array on the iPhone? Core data? NSUserDefaults? Should I maybe store every address object by itself, and not all objects in one NSMutableArray? In that case what should I do on the iPhone?
as #rog said, you may use NSUserDefaults to save data
& you should make your object follow protocal NSCoding
for examplem if you object is "YouObject"
#interface YouObject: NSObject {
}
#property (nonatomic, copy) NSString *uid;
#property (nonatomic, copy) NSString *name;
#end
//implement this 2 method
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
self.title = [decoder decodeObjectForKey:#"uid"];
self.author = [decoder decodeObjectForKey:#"name"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:title forKey:#"uid"];
[encoder encodeObject:author forKey:#"name"];
}
then archive or unarchive using NSUserDefaults
//archive
YouObject *object = [YouObject ....]
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:object ];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"address"];
//unarchive
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:#"address"];
YouObject *object = (YouObject *)[NSKeyedUnarchiver unarchiveObjectWithData:data];
or if you have a YouObject Array, you can save the NSArray in the same way;
//archive
NSArray *addresses;
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:address ];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"address"];
//unarchive
NSData *addressData = [[NSUserDefaults standardUserDefaults] objectForKey:#"address"];
NSArray *addresses = (NSArray*)[NSKeyedUnarchiver unarchiveObjectWithData:address];
For what you're describing, I think NSUserDefaults will suffice. See this post: How to store custom objects in NSUserDefaults. You can learn more about the limitations of NSUserDefaults here: What are the limitations of NSUserDefaults.
However, if you're saving/loading a large amount of data, then you should consider using Core Data.
Simplest way would to use the nsmutablearray read and write methods. All the data has to be plist data type nsarray nsdictionary nsstring nsnumber nsdate. Nsuserdefault like rog suggested is also good. As long as the amount of data remains small.

Possible to observe (KVO) every property of an NSObject?

I'm thingking of create a base class where every change made is immediately saved to NSUserDefaults (only KVO compilant parts of course), and automatically loads whenever that type of object is instantiated (a really basic, reusable user data store).
I have no intention to provide a "list of keys"-like constant to every subclass of this object, so I'm hoping that there is an automatic way to observe every property of an object.
Any ideas how to do this? With merely public API of course.
If you have a set of properties for an object, you can save them to a dictionary in NSUserDefaults. To save each property every time it is set you can create custom setter methods for each property using this:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"yourKey"] == nil) {
NSDictionary *dict = [NSDictionary dictionaryWithObject:#"yourObject" forKey:#"keyForYourObject"];
// Add stuff to the dictionary
[defaults setObject:dict forKey:#"yourKey"];
}else{
NSDictionary *dict = [defaults objectForKey:#"yourKey"];
// Add stuff to the dictionary
[defaults setObject:dict forKey:#"yourKey"];
}
This will give you a single dictionary stored in UserDefaults with all the properties. Then to get the list of keys use the standart method:
NSDictionary *dict = [[NSUserDefaults standardUserDefaults] objectForKey:#"yourKey"];
NSArray *keys = [dict allKeys];

Save NSArray to NSUserDefaults issues (using custom object in array)

I try to save my object to NSUserDefaults. But when I call this method again it is not have any info about previous operation.
There is my method below:
- (void)addToCart {
if([[NSUserDefaults standardUserDefaults] objectForKey:kCart]) {
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSMutableArray *products = [[NSMutableArray alloc] initWithArray:[prefs objectForKey:kCart]];
[products addObject:self.product];
[prefs setObject:products forKey:kCart];
[prefs synchronize];
[products release];
}
else {
//Saving...
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:[NSArray arrayWithObjects:self.product, nil] forKey:kCart];
[prefs synchronize];
}
}
I need to save a collection with a products to NSUserDefault. I wrap my object to NSArray and save it but it doesn't work.
Everything put into NSUserDefaults must be a valid property list object (NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary). All collection elements must themselves also be property list objects.
In order to save non-PL objects into NSUserDefaults, you must first convert the object into a PL object. The most generic way to do this is by serializing it to NSData.
Serializing to NSData is handled with NSKeyedArchiver. See Storing NSColor in User Defaults for the canonical example of this. (That document is very old and still references NSArchiver which will work fine for this problem, but NSKeyedArchiver is now the preferred serializer.)
In order to archive using NSKeyedArchiver, your object must conform to NSCoding as noted by #harakiri.
You need to conform to the <NSCoding> protocol and implement -initWithCoder: and -encodeWithCoder: in your custom object.
See: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Protocols/NSCoding_Protocol/Reference/Reference.html

Resources