How can I use UserDefaults to save/retrieve strings, booleans and other data in Swift?
-
5I am reopening this question because it can server as a good general question on this topic. The accepted answer is also more clear than the previous marked duplicate, which was also more specific than this question.Suragch– Suragch2017-11-30 02:00:21 +00:00Commented Nov 30, 2017 at 2:00
-
stackoverflow.com/a/53587688/6630644SPatel– SPatel2018-12-03 12:49:11 +00:00Commented Dec 3, 2018 at 12:49
-
I think this question is available in stack overflow you should search before add question hereYogesh Patel– Yogesh Patel2019-05-31 17:32:27 +00:00Commented May 31, 2019 at 17:32
-
For easiest explanation Check this out : youtube.com/watch?v=lMIx7H4u4lgMayur Prajapati - MeProgrammer– Mayur Prajapati - MeProgrammer2022-11-23 06:33:04 +00:00Commented Nov 23, 2022 at 6:33
16 Answers
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.
4 Comments
Best way to use UserDefaults
Steps
- Create extension of UserDefaults
- Create enum with required Keys to store in local
- Store and retrieve the local data wherever you want
Sample
extension UserDefaults{
//MARK: Check Login
func setLoggedIn(value: Bool) {
set(value, forKey: UserDefaultsKeys.isLoggedIn.rawValue)
//synchronize()
}
func isLoggedIn()-> Bool {
return bool(forKey: UserDefaultsKeys.isLoggedIn.rawValue)
}
//MARK: Save User Data
func setUserID(value: Int){
set(value, forKey: UserDefaultsKeys.userID.rawValue)
//synchronize()
}
//MARK: Retrieve User Data
func getUserID() -> Int{
return integer(forKey: UserDefaultsKeys.userID.rawValue)
}
}
enum for Keys used to store data
enum UserDefaultsKeys : String {
case isLoggedIn
case userID
}
Save in UserDefaults where you want
UserDefaults.standard.setLoggedIn(value: true) // String
UserDefaults.standard.setUserID(value: result.User.id!) // String
Retrieve data anywhere in app
print("ID : \(UserDefaults.standard.getUserID())")
UserDefaults.standard.getUserID()
Remove Values
UserDefaults.standard.removeObject(forKey: UserDefaultsKeys.userID)
This way you can store primitive data in best
Update You need no use synchronize() to store the values. As @Moritz pointed out the it unnecessary and given the article about it.Check comments for more detail
6 Comments
synchronize(), it's explained in the documentation. It's not only useless here but could slow down the defaults access.Swift 4 :
Store
UserDefaults.standard.set(object/value, forKey: "key_name")
Retrive
var returnValue: [datatype]? = UserDefaults.standard.object(forKey: "key_name") as? [datatype]
Remove
UserDefaults.standard.removeObject(forKey:"key_name")
1 Comment
UserDefault+Helper.swift
import UIKit
private enum Defaults: String {
case countryCode = "countryCode"
case userloginId = "userloginid"
}
final class UserDefaultHelper {
static var countryCode: String? {
set{
_set(value: newValue, key: .countryCode)
} get {
return _get(valueForKay: .countryCode) as? String ?? ""
}
}
static var userloginId: String? {
set{
_set(value: newValue, key: .userloginId)
} get {
return _get(valueForKay: .userloginId) as? String ?? ""
}
}
private static func _set(value: Any?, key: Defaults) {
UserDefaults.standard.set(value, forKey: key.rawValue)
}
private static func _get(valueForKay key: Defaults)-> Any? {
return UserDefaults.standard.value(forKey: key.rawValue)
}
static func deleteCountryCode() {
UserDefaults.standard.removeObject(forKey: Defaults.countryCode.rawValue)
}
static func deleteUserLoginId() {
UserDefaults.standard.removeObject(forKey: Defaults.userloginId.rawValue)
}
}
Usage:
Save Value:
UserDefaultHelper.userloginId = data["user_id"] as? String
Fetch Value:
let userloginid = UserDefaultHelper.userloginId
Delete Value:
UserDefaultHelper.deleteUserLoginId()
1 Comment
value(forKey:). That's from NSObject and key-value coding. Use the proper API provided by UserDefaults. That's object(forKey:).I would say Anbu's answer perfectly fine but I had to add guard while fetching preferences to make my program doesn't fail
Here is the updated code snip in Swift 5
Storing data in UserDefaults
@IBAction func savePreferenceData(_ sender: Any) {
print("Storing data..")
UserDefaults.standard.set("RDC", forKey: "UserName") //String
UserDefaults.standard.set("TestPass", forKey: "Passowrd") //String
UserDefaults.standard.set(21, forKey: "Age") //Integer
}
Fetching data from UserDefaults
@IBAction func fetchPreferenceData(_ sender: Any) {
print("Fetching data..")
//added guard
guard let uName = UserDefaults.standard.string(forKey: "UserName") else { return }
print("User Name is :"+uName)
print(UserDefaults.standard.integer(forKey: "Age"))
}
Comments
//Save
NSUserDefaults.standardUserDefaults().setObject("yourString", forKey: "YourStringKey")
//retrive
let yourStr : AnyObject? = NSUserDefaults.standardUserDefaults().objectForKey("YourStringKey")
1 Comment
You can use NSUserDefaults in swift this way,
@IBAction func writeButton(sender: UIButton)
{
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("defaultvalue", forKey: "userNameKey")
}
@IBAction func readButton(sender: UIButton)
{
let defaults = NSUserDefaults.standardUserDefaults()
let name = defaults.stringForKey("userNameKey")
println(name) //Prints defaultvalue in console
}
1 Comment
synchronize() command for NSUserDefaults to make sure your stuff is saved after doing a block of changes. This might have been more necessary in iOS 7 and earlier, but in iOS 8 and on, you should not call synchronize() in most situations. Check this for more Info: codingexplorer.com/nsuserdefaults-a-swift-introductionSwift 5 and above:
let defaults = UserDefaults.standard
defaults.set(25, forKey: "Age")
let savedInteger = defaults.integer(forKey: "Age")
defaults.set(true, forKey: "UseFaceID")
let savedBoolean = defaults.bool(forKey: "UseFaceID")
defaults.set(CGFloat.pi, forKey: "Pi")
defaults.set("Your Name", forKey: "Name")
defaults.set(Date(), forKey: "LastRun")
let array = ["Hello", "World"]
defaults.set(array, forKey: "SavedArray")
let savedArray = defaults.object(forKey: "SavedArray") as? [String] ?? [String()
let dict = ["Name": "Your", "Country": "YourCountry"]
defaults.set(dict, forKey: "SavedDict")
let savedDictionary = defaults.object(forKey: "SavedDictionary") as? [String: String] ?? [String: String]()
:)
1 Comment
I saved NSDictionary normally and able to get it correctly.
dictForaddress = placemark.addressDictionary! as NSDictionary
let userDefaults = UserDefaults.standard
userDefaults.set(dictForaddress, forKey:Constants.kAddressOfUser)
// For getting data from NSDictionary.
let userDefaults = UserDefaults.standard
let dictAddress = userDefaults.object(forKey: Constants.kAddressOfUser) as! NSDictionary
Comments
class UserDefaults_FavoriteQuote {
static let key = "appname.favoriteQuote"
static var value: String? {
get {
return UserDefaults.standard.string(forKey: key)
}
set {
if newValue != nil {
UserDefaults.standard.set(newValue, forKey: key)
} else {
UserDefaults.standard.removeObject(forKey: key)
}
}
}
}
Comments
One of the most important things, in my mind, when creating UserDefaults is to make them easy for me to use, re-use and also easy for others to use. Therefore I always make a UserDefaults key class that holdes the keys for my UserDefaults - thereby I am sure none can spell the key wrong. I also make a Util class with the UserDefaults functions for saving and fetching the stored values.
Let me show you:
struct UserDefaultKeys {
static let stringKey = "string-key"
}
And you use the key helper like this:
UserDefaultKeys.stringKey
Now to the helper class:
final class UserDefaultHelper {
static let standard = UserDefaultHelper()
func setString(stringToSave: String) {
UserDefaults.standard.set(userName, forKey: UserDefaultKeys.userKey)
}
func getString() -> String? {
return UserDefaults.standard.string(forKey: UserDefaultKeys.userKey)
}
}
And you use the helper class like this:
UserDefaultHelper.standard.setUserName(userName: "John")
1 Comment
setUserName(userName:) method on your UserDefaultHelper class. Why create a UserDefaultHelper class? Why not create an extension on UserDefaults to add a property named userName. Implement the get and set to call the standard set and string methods. And if you do that, there's no need to create public keys since no one else will need to know the keys.I have Created my Custom Functions for Store Data in Userdefualts
//******************* REMOVE NSUSER DEFAULT *******************
func removeUserDefault(key:String) {
UserDefaults.standard.removeObject(forKey: key)
}
//******************* SAVE STRING IN USER DEFAULT *******************
func saveInDefault(value:Any,key:String) {
UserDefaults.standard.setValue(value, forKey: key)
}
//******************* FETCH STRING FROM USER DEFAULT *******************
func fetchString(key:String)->AnyObject {
if (UserDefaults.standard.object(forKey: key) != nil) {
return UserDefaults.standard.value(forKey: key)! as AnyObject;
}
else {
return "" as AnyObject
}
}
1 Comment
value(forKey:) or setValue. That's from NSObject and key-value coding. Use the proper API provided by UserDefaults. That's object(forKey:) and set. Don't use synchronize(). It's documented as deprecated. And in Swift you don't need the ; at the end of lines or the ( ) on if statements.In class A, set value for key:
let text = "hai"
UserDefaults.standard.setValue(text, forKey: "textValue")
In class B, get the value for the text using the key which declared in class A and assign it to respective variable which you need:
var valueOfText = UserDefaults.value(forKey: "textValue")
1 Comment
value(forKey:) or setValue. That's from NSObject and key-value coding. Use the proper API provided by UserDefaults. That's object(forKey:) and set.Swift 4, I have used Enum for handling UserDefaults.
This is just a sample code. You can customize it as per your requirements.
For Storing, Retrieving, Removing. In this way just add a key for your UserDefaults key to the enum. Handle values while getting and storing according to dataType and your requirements.
enum UserDefaultsConstant : String {
case AuthToken, FcmToken
static let defaults = UserDefaults.standard
//Store
func setValue(value : Any) {
switch self {
case .AuthToken,.FcmToken:
if let _ = value as? String {
UserDefaults.standard.set(value, forKey: self.rawValue)
}
break
}
UserDefaults.standard.synchronize()
}
//Retrieve
func getValue() -> Any? {
switch self {
case .AuthToken:
if(UserDefaults.standard.value(forKey: UserDefaultsConstant.AuthToken.rawValue) != nil) {
return "Bearer "+(UserDefaults.standard.value(forKey: UserDefaultsConstant.AuthToken.rawValue) as! String)
}
else {
return ""
}
case .FcmToken:
if(UserDefaults.standard.value(forKey: UserDefaultsConstant.FcmToken.rawValue) != nil) {
print(UserDefaults.standard.value(forKey: UserDefaultsConstant.FcmToken.rawValue))
return (UserDefaults.standard.value(forKey: UserDefaultsConstant.FcmToken.rawValue) as! String)
}
else {
return ""
}
}
}
//Remove
func removeValue() {
UserDefaults.standard.removeObject(forKey: self.rawValue)
UserDefaults.standard.synchronize()
}
}
For storing a value in userdefaults,
if let authToken = resp.data?.token {
UserDefaultsConstant.AuthToken.setValue(value: authToken)
}
For retrieving a value from userdefaults,
//As AuthToken value is a string
(UserDefaultsConstant.AuthToken.getValue() as! String)
1 Comment
value(forKey:) or setValue. That's from NSObject and key-value coding. Use the proper API provided by UserDefaults. That's object(forKey:) and set.use UserDefault to store any settings value you want your application to remember between start ups, maybe you want to know ifs its been started before, maybe you want some values the user has set to be remembers so they don't have to be set very time, on Mac windows frames are stored in there for you, maybe you want to control the behaviour of the app, but you don't want it available to end users, you just want to choose just before your release. Be careful what you store in UserDefaults, it's not protected.
Comments
import Foundation
enum KeyName: String {
case associatedUserName = "associatedUserName"
}
class UserDefaultsManager {
let defaults = UserDefaults.standard
static let shared = UserDefaultsManager()
private init(){ }
/// Get Value for the Key Name
///
/// - Parameter key: Name of the Name which is of type KeyName
/// - Returns: Value of T type
fileprivate func getObject<T>(key:String) -> T? {
if let value = defaults.value(forKey: key), let castedValue = value as? T {
return castedValue
}
return nil
}
/// State Object to UserDeafults Key-Value pair against their Key Name
///
/// - Parameters:
/// - key: Key Name as String
/// - value: Value for the Key
fileprivate func setObject<T>(key:String, value:T) {
defaults.set(value, forKey: key)
}
}
extension UserDefaultsManager {
// AssociatedUserName
var hasAssociatedUserName: String {
get {
if let state: String = self.getObject(key: KeyName.associatedUserName.rawValue) {
return state
}
return EMPTY_STRING
}
set {
setObject(key: KeyName.associatedUserName.rawValue, value: newValue)
}
}
}
/** Usage:
//SET
UserDefaultsManager.shared.hasBeenAssociatedWithBeacon = "Brahma"
//GET
print(UserDefaultsManager.shared.hasBeenAssociatedWithBeacon)
*/