iOS store just a little bit of data - ios

I was wondering if there is a way to store small amounts of data, without going to a full-blown core-data API. I just need to store 6 'double' values somewhere... What's the best approach for that?
Thanks, Alex.

Core Data is just one way to store data, and it only makes sense when you need the things that it does. Here are five good options for storing your data:
Use NSUserDefaults. (Dead simple.)
Store the data in an appropriate structure (say, NSDictionary) and store it as a property list. (Pretty darn easy.)
Store the data in a class of your own design that implements NSCoding, and then write an instance of that class to a file using NSKeyedArchiver. (Works well for storing entire object graphs; this is basically what IB does. It might take an hour or two for the light to come on, but once you understand it this is a very nice way to read and write objects.)
Use Cocoa Touch's file system API, notably NSFileHandle and NSFileManager. (Conceptually simple if you've ever worked with a file system before. Puts you in complete control.)
Use the regular old POSIX file system API. (Best for existing Unix code, or code that you also want to compile on other platforms.)
Before you jump into any of those, read Apple's Archives and Serializations Programming Guide, User Defaults Programming Topics, and File System Programming Guide.

You can use NSUserDefaults to accomplish that (http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html).
-(void)saveToUserDefaults:(NSString*)myString
{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
if (standardUserDefaults) {
[standardUserDefaults setObject:myString forKey:#"Prefs"];
[standardUserDefaults synchronize];
}
}
-(NSString*)retrieveFromUserDefaults
{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
NSString *val = nil;
if (standardUserDefaults)
val = [standardUserDefaults objectForKey:#"Prefs"];
return val;
}

The easiest way to store small amounts of data without using some of the larger API's is the NSUserDefaults class. It's really easy to set up and use.

Related

App will load data stored in user defaults into memory at app launch?

I recently found that when I save, for example, 10MB data into user defaults and I relaunch app, the app's memory is larger about 10MB than previous launch according to Xcode memory report.
So I can't use NSUserDefaults to save large data for a good performance?
And the data is email messages, have notion of folder (inbox, trash, etc) and the messages' attachments need save to local. I know SQLite and I use it to store data that need for search, but it's some complex, I don't know whether CoreData is a good choice.
I planned to store emails to NSUserDefaults because it's very simple for I just implement NSCoding protocol, but now it seems not good solution for the memory issue.
// Save
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:mailFolders];
[userDefaults setObject:data forKey:#"myKey"];
[userDefaults synchronize];
// Read
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSData *mailData = [userDefaults objectForKey:#"myKey"];
NSArray *mailDataArray = [NSKeyedUnarchiver unarchiveObjectWithData:mailData];
NSLog(#"mail data size:%#", [NSByteCountFormatter stringFromByteCount:mailData.length countStyle:NSByteCountFormatterCountStyleFile]);
/**
mailFolder {
folderInfo,
messages
}
*/
i thnik there is no size limit to storing in NSUserDefaults.It's all upon device storage..
you can check this link
https://discussions.apple.com/thread/1763096?start=0&tstart=0
property lists should be used for data that consists primarily of strings and numbers. They are very inefficient when used with large blocks of binary data.
Tom,
There are many way in iOS to store the data.
1- NSUserDefault
2- Plist file
3- Data Base
If you have some small data then, NSUserDefaults and Plist is best option (no need to create database).
But if you have a large amount of data then, i would suggest you to use a proper DataBase (Sqlite OR CoreData).
NSUserDefaults is really meant for storing small pieces of data such as settings, preferences, and individual values.
Suggest using Core Data or SQLite to store a large list of elements.
There was a very good question about sqlite vs. Core Data;
Working with data in iOS Apps and Core Data vs SQLite 3 on Stack Overflow, you may want to read through the answers to that question.

Alternative to using a Singleton or AppDelegate for global data storage

I have an app that needs access to a set of user data that can't be stored on disk. My typical approach in the past would be to create a singleton to hold this data with a concurrent queue for each property to make data reads/writes thread safe.
What I am wondering is if there is a way to do this without the use of Singletons or storing a reference to my user data in my AppDelegate.
NSUserDefaults sounds like what you're looking for. According to Apple's documentation, "The NSUserDefaults class provides a programmatic interface for interacting with the defaults system. The defaults system allows an application to customize its behavior to match a user’s preferences." You can use NSUserDefaults in a global manner.
To do this, you need to first create an NSUserDefaults object:
NSUserDefaults *myAppDefaults = [NSUserDefaults myAppDefaults];
To save data to the defaults system, you would do something similar to the line below:
[standardDefaults setObject:#"Smith" forKey:#"lastName"];
Finally, you can retrieve your data from the defaults system by storing it in a variable. The line below shows how to set an NSString to be the value you originally stored:
NSString *lastName = [standardDefaults stringForKey:#"lastName"];

Is it ok to read a value stored in NSUserDefaults in multiple views

Is it ok to read a value stored in NSUserDefaults from multiple views or you only read it once and then you use another method to pass the data to different part of your app?
In other words I want to know if I’m doing it right, what I’m currently doing in an app I’m working on is basically saving a couple of NSIntegers and NSStrings (only two or three of each) in NSUserDefaults and then I’m reading those values in different parts of my app (different views) but I was wondering if this is a common practice or should I be doing something different like, read the value somewhere in the app and then try to use a different method to pass that data to other views. I want to learn best programming practices, that’s all.
What is the most common practice when using NSUserDefaults values in multiple parts of your app?
FYI,
I’m familiar with multiple ways to pass data between view controllers such as, delegation, prepareForSegue etc.
Thanks a lot.
I would also recommend, to read it multiple times and do not introduce another layer to hold the data.
The most important aspect is imo the actuality of the data, which might be changed inbetween different invocations.
It is ok to read and even write values to NSUserDefault in multiple places, but it is a better practice to have a global mechanism (like a singleton pattern) to read and write to UserDefaults. this way you'll be guaranteed to have fully synchronized values. all you need to do is to create a new class and add a few Class methods to read and write values from NSUserDefaults.
It is OK, when you call [NSUserDefaults standardUserDefaults] it will return the same object whether you spread the calls everywhere in the app or you encapsulate the access in a class.
I prefer the later as it allows you to have more readable code (and other benefits):
BOOL hasX = [TLPSettings hasPreferenceX];
if (hasX) {
[TLPSettings setY:YES];
}
vs
BOOL hasX = [[NSUserDefaults standardUserDefaults] boolForKey:#"hasX"];
if (hasX) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"hasY"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
You can change the preferences keys easily (without defining consts for them), change the validation or logic of a preference without messing with it everywhere, debug its usage or rogue values easily, store all or part of them in a different place, etc.
TLP is your three letter prefix.

Best way to store user information for my iOS app

What kind of database do you suggest? I want to store user email, username, password, and a couple other random pieces of information. It doesn't have to be fancy. Just a simple database. Are there any free options?
The user information needs to be stored in the keychain to keep it secure.
Any other information could be stored in any one of:
User defaults NSUserDefaults
File on disk (maybe a plist)
Database Core Data (technically just a file on disk)
Which you choose depends on what the data is, how much there is and what kind of access you need to it.
If your data is small and chosen by the user as some kind of setting then user defaults makes sense and is the lowest cost for you to implement.
To use a database, check out Core Data intro.
Wain is right but I think as you want to store small amount of data for further use, the most efficient ways is to use NSUserDefault.
NSUserDefault stores data in NSDictionary type things.
I think this is the step you have to take:
1- check if data exists. I mean if user selected the number if the last run of your app. So in viewDidLoad method:
NSMutableDictionary *userDefaultDataDictionary = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:ALL_DATA_KEY] mutableCopy];
if (userDefaultDataDictionary) {
// so the dictionary exists, which means user has entered the number in previous app run
// and you can read it from the NSDictionaty:
if(userDefaultDataDictionary[LABLE_KEY]){
//and store it
}
}
2 - you can implement some method like syncronize to store data in NSUserDefault every time something has been changed.
- (void) synchronize
{
NSMutableDictionary *dictionaryForUserDefault = [[[NSUserDefaults standardUserDefaults] dictionaryForKey:ALL_DATA_KEY] mutableCopy];
if(!dictionaryForUserDefault)
dictionaryForUserDefault = [[NSMutableDictionary alloc] init];
dictionaryForUserDefault[LABLE_KEY] = //data you want to store
[[NSUserDefaults standardUserDefaults] setObject:dictionaryForUserDefault forKey:ALL_DATA_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
}
P.S. and don't forget to #define your keys for your dictionary:
#define LABLE_KEY #"Lables"
#define ALL_DATA_KEY #"AllData"
Store it in a plist. If you're talking about data pertaining to one or a few users, that's probably the easy thing. here is a simple example.
Since you say database, store in Sqlite. There's some provided stuff for it already in xcode.
The entire database is contained in one file, which can be moved around if you need to.
Here is some more information on how to use one in your app.

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