24

I am new to iOS development and Mobile app development in general, I have decent knowledge about Objective C and MVC patterns to be used and I have never done any Mac development.

I am struggling to understand what NSUserDefaults is for?

We already have something like PList which stores data as XML and we have SQLite which is lightweight DB for such devices.

Then why do we have it?

Is it an alternative simple key-value storage for our app in the same way we have different types of storage on the cloud like an RDBMS and a key-value based NoSQL store etc ?

For NSUserDefaults, Apple docs say that :-

"Applications record such preferences by assigning values to a set of parameters in a user’s defaults database"

What do they mean by user's default database?

My guess is that, like in any multi-user operating system we have various user accounts and in the same way in Mac as well we might be having multiple users each having a database from where applications would load saved preferences for that user.

So like Mac OS X, does iOS also have multiple users and depending upon whichever is logged in NSUserDefaults picks his/her preferences?

Please tell me if I am wrong.

Piyush Dubey
  • 2,416
  • 1
  • 24
  • 39
Amogh Talpallikar
  • 12,084
  • 13
  • 79
  • 135

5 Answers5

15

One thing that hasn't been mentioned yet: NSUserDefaults supports all basic scalar (float, int, BOOL) types, as well as the plist-compatible types: NSData, NSString, NSNumber, NSDate, NSArray, and NSDictionary. (You mentioned plists as an alternative--NSUserDefaults is just a front-end to a standard plist file in the application's Preferences folder.) This makes it easy to create persistent storage for your application state in just a few lines of code. Even better, if you implement NSCoding on your model objects, you can archive them into an NSData and put them in NSUserDefaults:

NSData* data = [NSKeyedArchiver archivedDataWithRootObject:arrayOfModelObjects];

[[NSUserDefaults standardUserDefaults] setObject:data forKey:kDefaultsKeyModelObjects];

and restoring your app data is as simple as

- (void)viewDidLoad
{
    NSData* data = [[NSUserDefaults standardUserDefaults] objectForKey:kDefaultsKeyModelObjects];

    arrayOfModelObjects = [[NSKeyedUnarchiver unarchiveRootObject:data] retain];

    // error checking, tell UI to load the new values, etc...
}

(kDefaultsKeyModelObjects is a string constant you've defined somewhere. Always put your NSUserDefaults keys in one place! Having a typo in a key name can take hours to debug. :)

If you used, e.g., SQLite to store your application data, you have to write a lot of code to move your model data in and out of the database. That makes sense if you're dealing with a lot of data, need efficient searching, etc.; but if it's, say, a list of servers in a networking app, it's easier and cleaner to throw them in NSUserDefaults.

One last thing: NSUserDefaults is great for prototyping. Even if you know you're going to need a SQLite store eventually, you can start out using NSUserDefaults as a quick-and-easy persistent store, and get your UI working and your data model fleshed out before writing a bunch of database code.

So like Mac OS X, does iOS also have multiple users and depending upon whichever is logged in NSUserDefaults picks his/her preferences ?

Nope, on iOS the defaults plist is in the application's Library/Preferences folder, not in a user-specific folder like it is on OS X. I can't imagine iOS will ever have multiple logins, but you never know. If it did, they'd have to make separate defaults plists for different users.

davehayden
  • 3,484
  • 21
  • 28
14

NSUserDefaults are used to save small portions of data the App is dependent on to run correctly, while other approaches are good to store bigger amounts of data, that the app work with.

NSUserDefaults makes is incredible easy, as you don't have to worry about files, entities, fetches,…. It is all done in one line.

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
  • 1
    i store some value in NSUserDefaults to use it on Relaunch of the app. but i get nil value sometime after long time of relaunch the app. – freelancer Sep 05 '12 at 05:52
  • is this a question? write a new one with all relevant code, as NSUserDefaults should store informations permanently. – vikingosegundo Sep 05 '12 at 10:46
4

It's originally for storing settings, but does seem to get (ab)used for a lot of other things if the questions on SO are anything to go by. The "point" of it is that it provides a single-line data persistence and retrieval method for a wide range of data types.

There is no multi-user configuration (yet?) on iOS (have you ever had to sign in to your iPhone?) that is built in to NSUserDefaults, but because OS X and iOS are built on the same foundation, the same class is used for both operating systems.

jrturton
  • 118,105
  • 32
  • 252
  • 268
  • So NSUserDefaults role in MacOsX was to store settings as key-value in user'd default database from where applications can pick up data. But tell me, in iOS is just a simple key value storage because there is only one user so the name NS"User"Defaults as such has no significance here? No doubt.. it is being (ab)used :P So what exactly is its use-case in iOS ? Sorry for being little silly but I dont own an iphone. I did a lot of web dev in my grad and have to work on iOS in my company. – Amogh Talpallikar Jan 10 '12 at 11:27
  • This should have been selected as the correct answer. The original question: "So like Mac OS X, does iOS also have multiple users and depending upon whichever is logged in NSUserDefaults picks his/her preferences ?" was not addressed from the other answer. – user523234 May 01 '12 at 16:04
3

iOS is a single-user OS. Hence, NSUserDefaults is used differently in OSX and iOS.

In iOS, you normally use NSUserDefaults to save application preferences and/or user data on the "iOS defaults system". Data saved in the defaults system will be persistent at all time even when you reboot the iOS device. As a matter of fact, even when the user updates the application.

You typically want to use NSUserDefaults to save application preferences/settings. Any other massive data such as game data or realtime calculations should be save in CoreData or sqllite in the documents directory.

Semere Taézaz Sium
  • 4,036
  • 3
  • 21
  • 26
  • @AnkitJain Another thread suggests that's not true, outside of glitches: http://stackoverflow.com/questions/1638766/do-nsuserdefaults-persist-through-an-update-to-an-app-in-the-appstore – Dave Jun 09 '13 at 18:36
1

NSUserDefaults stored values for only your application.

Note - It is not meant to serve as a replacement for a traditional store for data (Core Data, SQLite, Property Lists, etc are meant for storing application data). What NSUserDefaults is meant for is for specific key value pairs.

For example, I use it to store an authenticated user's networkid and full name once the login process is done. Upon session timeout or logout, I clear those values. For this NSUserDefaults shines.

Meet Doshi
  • 4,241
  • 10
  • 40
  • 81
LJ Wilson
  • 14,445
  • 5
  • 38
  • 62
  • So is NSUserDefaults kind of temporary storage for an applications session ? same as sessions storage in a web application ? – Amogh Talpallikar Jan 10 '12 at 11:16
  • No. NSUserDefaults is for persistent storage. The total opposite of temporary. If you want your data to be there at all time and if it is fairly small, then go ahead and save it in NSUserDefaults. Let's say you are developing a game and your app consists of a settings View for the user to choose options such as "Nick Name", color, speed etc, then you should use NSUserDefaults to save those user preferences. You can also use plist and sql-lite but the best practice suggested by most iOS developers is to use NSUserDefaults for app settings. – Semere Taézaz Sium Jan 10 '12 at 11:28