# Working with UserDefaults in iOS

## Features

* The UserDefaults class provides access to the user's defaults database.
    
* It stores data persistently across the app launches as long as the app is installed.
    
* Access to the data is private to the app unless shared through App Groups.
    
* Access to this database is thread-safe.
    
* It is a key-value store that works through a property list (plist) file.
    
* Supported data types include String, Bool, Date, Array, Dictionary, Data and Numbers.
    
* Custom objects can be stored by encoding them as data.
    
* We can use this to store non-sensitive data such as user preferences.
    

## Usage

### Utilising the default shared instance of UserDefaults.

```swift
import Foundation
// Set a key value in UserDefaults
UserDefaults.standard.set("Shivam", forKey: "firstname")
// Get a key value from User Defaults
UserDefaults.standard.value(forKey: "firstname")
// Empty User Defaults
UserDefaults.standard.removeObject(forKey: "firstname")
```

### Creating a UserDefaults that can be shared with multiple apps and extensions.

```swift
import Foundation
// User Defaults with Suite.
// Useful for sharing data with other apps
// or extensions with app groups.
let defaults = UserDefaults(suiteName: "group.com.organisation.appname")! 
// Set a key value in User Defaults
defaults.set("Shivam", forKey: "firstname") 
// Get a key value from User Defaults
defaults.value(forKey: "firstname") 
// Empty User Defaults
defaults.removeObject(forKey: "firstname")
```

### Storing custom objects in UserDefaults.

```swift
import Foundation
// Custom model to be stored in UserDefaults
struct Student: Codable {
    let firstname: String
    let lastname: String
    let grade: Int
    let subjects: Array<String>
    let teachers: [String: String]
    let profileImage: Data
    let dateModified: Date
}

// Student Object
let student = Student(firstname: "John",
                      lastname: "Doe",
                      grade: 2,
                      subjects: ["Hindi", "English", "Maths"],
                      teachers: ["Hindi": "Teacher A", "English": "Teacher b", "Maths": "Teacher X"],
                      profileImage: Data(),
                      dateModified: Date())

// Encode custom object to data and store it in UserDefaults
let encoder = JSONEncoder()
do {
    let data = try encoder.encode(student)
    UserDefaults.standard.setValue(data, forKey: "StudentData")
} catch {
    throw error
}

// Retrieve data from UserDefaults and decode it to custom object
let decoder = JSONDecoder()
if let data = UserDefaults.standard.value(forKey: "StudentData") as? Data {
    do {
        let object = try decoder.decode(Student.self, from: data)
        print(object)
    } catch {
        throw error
    }
} else {
    print("No data in UserDefaults.")
}
```

### Using UserDefaults as a Property Wrapper

Check out this [gist to use UserDefaults with Property Wrapper](https://gist.github.com/shivammaggu/451e06aafc8b25ba8ca9479a8f9ab175). This is a more generalized way to use in Projects.

%[https://gist.github.com/shivammaggu/451e06aafc8b25ba8ca9479a8f9ab175]
