Difference Between Userdefaults() and Userdefaults.Standard

Difference between UserDefaults() and UserDefaults.standard

UserDefaults - Gives you a new object, each object is allocated a different memory and deallocated when object scope is finished.

UserDefaults.standard - Gives you the singleton object by using the class method standard the object received by this method is allocated single memory throughout the application.

And the usage of them if you´re interesedted in that:

// Set
UserDefaults.standard.set("YOUR STRING", forKey: "key")
UserDefaults().set("YOUR STRING", forKey: "key")

// Get
UserDefaults.standard.string(forKey: "key")
UserDefaults().string(forKey: "key")

NSUserDefault , Alloc init vs standard Userdefault

NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];

This is a class method will will return the shared instance of the NSUserDefaults. As it is a shared instance. It is the ideal place to store data at a global level, to access across your application.

NSUserDefaults *userDefault = [[NSUserDefaults alloc] init];

This is an instance method which will initialize an allocated instance of NSUserDefaults. As every-time this is called, a new instance is initialized and returned, this would not be useful to store data at a global level. Hence more suited when at an intra-class level. Also, this instance's lifetime will be valid only till its scope of reference is present.

More info here: Documentation

To access standard defaults in Simulator/Device: link

What are all the OS keys of UserDefaults and what do they mean?

The set of keys is not fixed or, in general, documented. Any string can be used as a key.

UserDefaults.standard is a global object in your app. So any framework used in your app has access to UserDefaults.standard and can set own entries, using any keys it wants. Some settings are even shared across the whole system and so they can be set by other apps or by frameworks you don't use in your app.

The keys and values used by an app or framework are usually considered to be implementation details, so Apple doesn't want you to rely on anything their code stores in UserDefaults.standard.

You would need to read the source code of an app or framework to understand what keys it might set and what they mean, but Apple releases very little of its source code. You could also try reverse-engineering the app or framework (that is, disassembling it and figuring out what it does from the machine instructions) but that is usually very difficult.

UserDefaults or Core Data?

NSUserDefaults as the name suggests (vaguely) should be used for storing preferences and app settings only. You should not be storing critical data and or user data into them.

CoreData is a full fledged persistent framework which supports large data transactions. CoreData allows you to build relational entity–attribute model for storing user data.

Please note that CoreData is a framework and can use SQLite, binary formats to store data (the default templates always use SQLite).

Example:

App preferences like show notifications, toggle switch settings, UISegmentedControl settings all go into NSUserDefaults. Whereas any data you might fetch using a web service like a list of all cities in a country, list of todos for a user go into CoreData.

PS: I don't recommend wiki for technical write-ups but to get quick understanding on CoreData, please refer here!

Pros of NSUserDefaults:

  • Easy to store and retrieve data.
  • Useful for storing default values with minimum fuzz.

Cons of NSUserDefaults:

  • Not suitable for large data sets

  • Performance hit when you try to store and load large amount of data
    All or nothing approach

Pros of CoreData:

  • Reliable framework to interact and query against data

  • Can be extremely fast when setup correctly (with relationships)

  • Powerful capabilities

Cons of CoreData

  • Takes time to master and learn the core concept

  • Needs proper app architecture design to be efficient

  • You cannot have a learn and implement in a day approach with CoreData

  • As you improve your app, you need to improve your data architecture
    as well

  • Migrating to new versions can be a pain if you are not careful.

Reference From HERE.

Is it fine to access NSUserDefaults/UserDefaults frequently?

Your code is just fine. Don't worry about such optimizations until you actually encounter an issue. Trust that UserDefaults is implemented smartly (because it is). There is nothing "laggy" about setting something as simple as a Bool in UserDefaults.

You also wish to review another one of my answers which is related to this question: When and why should you use NSUserDefaults's synchronize() method?

What are the consequences of using UserDefaults.standard in tests?

The test, run in isolation, will work. But here's another problem: it aggressively clears user defaults. This will cause problems for anyone who wants to do manual testing after running this test.

A safer approach would be to have setUp() remember the current value (if any), then restore it in tearDown().

The safest approach would be to use a fake.

Store my custom Class in UserDefaults, and casting(parsing) this UserDefault to reach values (Swift 4.2)

You can't store a class instance without conforming to NSCoding / Codable protocols

class UserDetail : Codable  {
var accountIsDeleted:Bool? // you can remove this as it's useless if the you read a nil content from user defaults that means no current account
var userGUID : String?
var userAge: Int?
}

store

do { 
let res = try JSONEncoder().encode(yourClassInstance)
UserDefaults.standard.set(value:res,forKey: "somekey")
}
catch { print(error) }

retrieve

do {
if let data = UserDefaults.standard.data(forKey:"somekey") {
let res = try JSONDecoder().decode(UserDetail.self,from:data)
} else {
print("No account")
}
}
catch { print(error) }

How can I use UserDefaults in Swift?

ref: NSUserdefault objectTypes

Swift 3 and above

Store

UserDefaults.standard.set(true, forKey: "Key") //Bool
UserDefaults.standard.set(1, forKey: "Key") //Integer
UserDefaults.standard.set("TEST", forKey: "Key") //setObject

Retrieve

 UserDefaults.standard.bool(forKey: "Key")
UserDefaults.standard.integer(forKey: "Key")
UserDefaults.standard.string(forKey: "Key")

Remove

 UserDefaults.standard.removeObject(forKey: "Key")

Remove all Keys

 if let appDomain = Bundle.main.bundleIdentifier {
UserDefaults.standard.removePersistentDomain(forName: appDomain)
}

Swift 2 and below

Store

NSUserDefaults.standardUserDefaults().setObject(newValue, forKey: "yourkey")
NSUserDefaults.standardUserDefaults().synchronize()

Retrieve

  var returnValue: [NSString]? = NSUserDefaults.standardUserDefaults().objectForKey("yourkey") as? [NSString]

Remove

 NSUserDefaults.standardUserDefaults().removeObjectForKey("yourkey")


Register

registerDefaults: adds the registrationDictionary to the last item in every search list. This means that after NSUserDefaults has looked for a value in every other valid location, it will look in registered defaults, making them useful as a "fallback" value. Registered defaults are never stored between runs of an application, and are visible only to the application that registers them.

Default values from Defaults Configuration Files will automatically be registered.

for example detect the app from launch , create the struct for save launch

struct DetectLaunch {
static let keyforLaunch = "validateFirstlunch"
static var isFirst: Bool {
get {
return UserDefaults.standard.bool(forKey: keyforLaunch)
}
set {
UserDefaults.standard.set(newValue, forKey: keyforLaunch)
}
}
}

Register default values on app launch:

UserDefaults.standard.register(defaults: [
DetectLaunch.isFirst: true
])

remove the value on app termination:

func applicationWillTerminate(_ application: UIApplication) {
DetectLaunch.isFirst = false

}

and check the condition as

if DetectLaunch.isFirst {
// app launched from first
}

UserDefaults suite name

another one property suite name, mostly its used for App Groups concept, the example scenario I taken from here :

The use case is that I want to separate my UserDefaults (different business logic may require Userdefaults to be grouped separately) by an identifier just like Android's SharedPreferences. For example, when a user in my app clicks on logout button, I would want to clear his account related defaults but not location of the the device.

let user = UserDefaults(suiteName:"User")

use of userDefaults synchronize, the detail info has added in the duplicate answer.

UserDefaults between Objective-C and Swift

[NS]UserDefaults is backed by a plist and a dictionary. The Objective-C string was saved to the plist as a <string>Some Text</string>.

That same plist loaded in Swift gives a string for that key.

So you should have no issue using UserDefaults.string to read the value stored with Objective-C. Of course you still need to verify the value actually exists.

if let str = UserDefaults.standard.string(forKey: "textKey") {
print("Found \(str)")
} else {
print("No string for key")
}

Even if the original value isn't a string, using UserDefault.string is safe. It will simply return nil for non-string values.

With regard to NSDictionary and NSMutableDictionary, note that UserDefaults only retrieves immutable NSDictionary. You can't read an NSMutableDictionary (or array) from UserDefaults.

Note you can safely use a Swift dictionary to read the original NSDictionary. No need to use Objective-C classes.



Related Topics



Leave a reply



Submit