¿Cómo puedo usar UserDefaults en Swift?

119

¿Cómo puedo usar UserDefaults para guardar / recuperar cadenas, valores booleanos y otros datos en Swift?

Mithun Ravindran
fuente
4
Estoy reabriendo esta pregunta porque puede servir como una buena pregunta general sobre este tema. La respuesta aceptada también es más clara que el duplicado marcado anteriormente , que también era más específico que esta pregunta.
Suragch
Creo que esta pregunta está disponible en el desbordamiento de pila, debe buscar antes de agregar la pregunta aquí
Yogesh Patel

Respuestas:

330

ref: NSUserdefault objectTypes

Swift 3 y superior

Tienda

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

Recuperar

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

Eliminar

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

Quitar todas las claves

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

Swift 2 y menos

Tienda

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

Recuperar

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

Eliminar

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


Registrarse

registerDefaults: agrega el registrationDictionary al último elemento de cada lista de búsqueda. Esto significa que después de que NSUserDefaults haya buscado un valor en todas las demás ubicaciones válidas, buscará los valores predeterminados registrados, lo que los hará útiles como un valor "alternativo". Los valores predeterminados registrados nunca se almacenan entre ejecuciones de una aplicación y solo son visibles para la aplicación que los registra.

Los valores predeterminados de los archivos de configuración predeterminados se registrarán automáticamente.

por ejemplo, detectar la aplicación desde el lanzamiento, crear la estructura para guardar el lanzamiento

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

Registre los valores predeterminados al iniciar la aplicación:

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

eliminar el valor en la terminación de la aplicación:

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

}

y verifique la condición como

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

Nombre de la suite de valores predeterminados de usuario

otro nombre de conjunto de propiedades , principalmente se usa para el concepto de Grupos de aplicaciones , el escenario de ejemplo que tomé de aquí :

El caso de uso es que quiero separar mis UserDefaults (diferentes lógicas comerciales pueden requerir que los Userdefaults se agrupen por separado) por un identificador como las SharedPreferences de Android. Por ejemplo, cuando un usuario en mi aplicación hace clic en el botón Cerrar sesión, me gustaría borrar los valores predeterminados relacionados con su cuenta, pero no la ubicación del dispositivo.

let user = UserDefaults(suiteName:"User")

uso de la sincronización de valores predeterminados de usuario , la información detallada se ha agregado en la respuesta duplicada.

Anbu.Karthik
fuente
¿Cuándo y dónde debería llamar a los métodos de la tienda? ¿Justo antes de que se cierre la aplicación o cada vez que cambien los valores?
josef
bastante impresionante, un lugar para todo tipo de operaciones.
Michaeln Peterson
@ Anbu.Karthik ¿cómo actualizará el valor de una clave en los valores predeterminados del usuario?
sathya chinnasamy
2
@RajeshBaidya - userdefault siempre almacena solo el valor final
Anbu.Karthik
¿Estos datos persisten durante la instalación / desinstalación de la aplicación?
OrangePot
40

La mejor forma de utilizar UserDefaults

Pasos

  1. Crear extensión de UserDefaults
  2. Crear enumeración con las claves necesarias para almacenar en local
  3. Almacene y recupere los datos locales donde quiera

Muestra

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)
    }
}

enumeración para las claves utilizadas para almacenar datos

enum UserDefaultsKeys : String {
    case isLoggedIn
    case userID
}

Guarda en UserDefaults donde quieras

UserDefaults.standard.setLoggedIn(value: true)          // String
UserDefaults.standard.setUserID(value: result.User.id!) // String

Recupere datos en cualquier lugar de la aplicación

print("ID : \(UserDefaults.standard.getUserID())")
UserDefaults.standard.getUserID()

Eliminar valores

UserDefaults.standard.removeObject(forKey: UserDefaultsKeys.userID) 

De esta forma, puede almacenar datos primitivos de la mejor manera

Actualización No es necesario utilizar sincronizar () para almacenar los valores. Como @Moritz señaló que es innecesario y dio el artículo al respecto.Consulte los comentarios para obtener más detalles.

iSrinivasan27
fuente
No es necesario synchronize(), se explica en la documentación. No solo es inútil aquí, sino que podría ralentizar el acceso predeterminado.
Eric Aya
Sí, se menciona en el doc. Una vez que se cambian los datos predeterminados, se guardarán automáticamente, pero en algunos casos es posible que sus valores no se almacenen, es decir, de forma asíncrona. Así que pensé que era mejor sincronizar.
iSrinivasan27
2
No es mejor, a veces incluso es la fuente de problemas. No uses la sincronización, es obsoleta y problemática. Consulte codingexplorer.com/nsuserdefaults-a-swift-introduction, en particular la parte de "actualización". También realicé muchas pruebas sobre esto y eliminé todas las llamadas para sincronizar en todas mis aplicaciones y nunca tuve un problema, incluso en situaciones extremas. Pero bueno, si te gustan las cosas inútiles que pueden ralentizar tu aplicación, sincroniza la llamada ... seguro ...;)
Eric Aya
Es muy útil. He comentado sync (). El uso de sync () se basa en necesario.
iSrinivasan27
hola cómo guardar datos en nsuserdefaults en un archivo separado en Swift
Dilip Tiwari
15

Rápido 4 :

Tienda

    UserDefaults.standard.set(object/value, forKey: "key_name")

Recuperar

    var returnValue: [datatype]? = UserDefaults.standard.object(forKey: "key_name") as? [datatype]

Eliminar

    UserDefaults.standard.removeObject(forKey:"key_name") 
Nikunj Joshi
fuente
¿Qué quiere decir con esta línea 'UserDefaults.standard.synchronize ()' como opcional? @NikunjJoshi
Nishad Arora
2
//Save
NSUserDefaults.standardUserDefaults().setObject("yourString", forKey: "YourStringKey")

//retrive
let yourStr : AnyObject? = NSUserDefaults.standardUserDefaults().objectForKey("YourStringKey")
Dharmesh Kheni
fuente
En Swift 3: let minutes = UserDefaults.standard.object (forKey: "minutes") as! String
Alessandro Mattiuzzi
2

Puedes usarlo NSUserDefaultsrápidamente de esta manera,

@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
}
DHEERAJ
fuente
2
La primera versión de esta publicación decía usar el synchronize()comando para NSUserDefaultsasegurarse de que sus cosas se guarden después de hacer un bloque de cambios. Esto podría haber sido más necesario en iOS 7 y versiones anteriores, pero en iOS 8 y posteriores, no debería llamar a syncize () en la mayoría de las situaciones. Consulte esto para obtener más información: codingexplorer.com/nsuserdefaults-a-swift-introduction
Dharmesh Kheni
2

Swift 5 y superior:

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]()

:)

Xab Ion
fuente
1

Guardé NSDictionary normalmente y pude obtenerlo correctamente.

 dictForaddress = placemark.addressDictionary! as NSDictionary
        let userDefaults = UserDefaults.standard
        userDefaults.set(dictForaddress, forKey:Constants.kAddressOfUser)

// Para obtener datos de NSDictionary.

let userDefaults = UserDefaults.standard
    let dictAddress = userDefaults.object(forKey: Constants.kAddressOfUser) as! NSDictionary
Chandni
fuente
Gracias por su ayuda señorita. :)
Venkatesh
1
class UserDefaults_WorstPresidentName {
    static let key = "appname.worstPresidentName"

    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)
            }
        }
    }
}
neoneye
fuente
1

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)
 }
}

Uso:

Ahorre valor:

UserDefaultHelper.userloginId = data["user_id"] as? String

Obtener valor:

let userloginid = UserDefaultHelper.userloginId

Eliminar valor:

UserDefaultHelper.deleteUserLoginId()
Mannam Brahman
fuente
1

Diría que la respuesta de Anbu está perfectamente bien, pero tuve que agregar guardia mientras buscaba las preferencias para que mi programa no fallara

Aquí está el fragmento de código actualizado en Swift 5

Almacenamiento de datos en 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

    }

Obteniendo datos de 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"))
    }
SwiftBoy
fuente
0

En clase A, establezca el valor de la clave:

let text = "hai"  
UserDefaults.standard.setValue(text, forKey: "textValue")

En clase B, obtenga el valor para el texto usando la clave que declaró en clase Ay asígnelo a la variable respectiva que necesita:

var valueOfText  = UserDefaults.value(forKey: "textValue")
K.Gowri Manohari
fuente
0

Swift 4, he usado Enum para manejar UserDefaults.

Este es solo un código de muestra. Puede personalizarlo según sus requisitos.

Para almacenar, recuperar, quitar. De esta manera, simplemente agregue una clave para su clave UserDefaults a la enumeración. Maneje los valores mientras obtiene y almacena según el tipo de datos y sus requisitos.

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()
    }
}

Para almacenar un valor en los valores predeterminados del usuario,

if let authToken = resp.data?.token {
     UserDefaultsConstant.AuthToken.setValue(value: authToken)
    }

Para recuperar un valor de los valores predeterminados del usuario,

//As AuthToken value is a string
    (UserDefaultsConstant.AuthToken.getValue() as! String)
Pramod Más
fuente