Come posso utilizzare UserDefaults in Swift?


119

Come posso utilizzare UserDefaults per salvare / recuperare stringhe, valori booleani e altri dati in Swift?


4
Riaperro questa domanda perché può servire come una buona domanda generale su questo argomento. La risposta accettata è anche più chiara del precedente duplicato contrassegnato , che era anche più specifico di questa domanda.
Suragch


Penso che questa domanda sia disponibile nello stack overflow, dovresti cercare prima di aggiungere la domanda qui
Yogesh Patel

Risposte:


330

ref: NSUserdefault objectTypes

Swift 3 e versioni successive

Negozio

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

Recuperare

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

Rimuovere

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

Rimuovi tutte le chiavi

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

Swift 2 e versioni precedenti

Negozio

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

Recuperare

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

Rimuovere

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


Registrati

registerDefaults: aggiunge il registrationDictionary all'ultimo elemento in ogni elenco di ricerca. Ciò significa che dopo che NSUserDefaults ha cercato un valore in ogni altra posizione valida, cercherà nei valori predefiniti registrati, rendendoli utili come valore di "riserva". I valori predefiniti registrati non vengono mai memorizzati tra le esecuzioni di un'applicazione e sono visibili solo all'applicazione che li registra.

I valori predefiniti dei file di configurazione predefiniti verranno registrati automaticamente.

ad esempio rileva l'app dal lancio, crea la struttura per il salvataggio del lancio

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

Registra i valori predefiniti all'avvio dell'app:

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

rimuovi il valore alla chiusura dell'app:

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

}

e controlla le condizioni come

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

Nome della suite UserDefaults

un altro nome di suite di proprietà , principalmente utilizzato per il concetto di gruppi di app , lo scenario di esempio che ho preso da qui :

Il caso d'uso è che desidero separare i miei UserDefaults (una logica di business diversa potrebbe richiedere il raggruppamento separato di Userdefaults) da un identificatore proprio come SharedPreferences di Android. Ad esempio, quando un utente nella mia app fa clic sul pulsante di disconnessione, desidero cancellare le impostazioni predefinite relative all'account ma non la posizione del dispositivo.

let user = UserDefaults(suiteName:"User")

l'uso di userDefaults sincronizza , le informazioni dettagliate sono state aggiunte nella risposta duplicata.


Quando e dove dovresti chiamare i metodi del negozio? Appena prima che l'app si chiuda o ogni volta che i valori cambiano?
josef

davvero fantastico, un posto per tutti i tipi di operazioni.
michaeln peterson

@ Anbu.Karthik come aggiornerete il valore per una chiave in userdefaults?
sathya chinnasamy

2
@RajeshBaidya - userdefault salva sempre solo il valore finale
Anbu.Karthik

Questi dati persistono durante l'installazione / disinstallazione dell'app?
OrangePot

40

Il modo migliore per utilizzare UserDefaults

passi

  1. Crea l'estensione di UserDefaults
  2. Crea enum con le chiavi richieste da archiviare in locale
  3. Archivia e recupera i dati locali dove vuoi

Campione

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 per le chiavi utilizzate per memorizzare i dati

enum UserDefaultsKeys : String {
    case isLoggedIn
    case userID
}

Salva in UserDefaults dove vuoi

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

Recupera i dati ovunque nell'app

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

Rimuovi valori

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

In questo modo puoi archiviare al meglio i dati primitivi

Aggiorna Non è necessario utilizzare synchronize () per memorizzare i valori. Come @ Moritz ha sottolineato che non è necessario e dato l'articolo su di esso, controlla i commenti per maggiori dettagli


Non serve synchronize(), è spiegato nella documentazione. Non solo è inutile qui, ma potrebbe rallentare l'accesso alle impostazioni predefinite.
Eric Aya

Sì, è menzionato nel doc. Una volta modificati i dati predefiniti, verranno salvati automaticamente ma in alcuni casi i valori potrebbero non essere archiviati, ovvero asincroni. Quindi ho pensato che fosse meglio sincronizzare.
iSrinivasan27

2
Non è migliore, a volte è anche la fonte dei problemi. Non utilizzare la sincronizzazione, è obsoleta e problematica. Vedi codingexplorer.com/nsuserdefaults-a-swift-introduction in particolare la parte "aggiornamento". Ho anche eseguito molti test su questo e rimosso tutte le chiamate per la sincronizzazione in tutte le mie app e non ho mai avuto problemi anche in situazioni terribili. Ma hey, se ti piacciono le cose inutili che possono rallentare la tua app, chiama sync ... certo ...;)
Eric Aya

È davvero utile. Ho commentato sync (). L'uso di sync () si basa sul necessario.
iSrinivasan27

ciao come salvare i dati in nsuserdefaults in un file separato in swift
Dilip Tiwari

15

Swift 4 :

Negozio

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

retrive

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

Rimuovere

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

cosa intendi con questa riga "UserDefaults.standard.synchronize ()" come opzionale? @NikunjJoshi
Nishad Arora

2
//Save
NSUserDefaults.standardUserDefaults().setObject("yourString", forKey: "YourStringKey")

//retrive
let yourStr : AnyObject? = NSUserDefaults.standardUserDefaults().objectForKey("YourStringKey")

In Swift 3: let minutes = UserDefaults.standard.object (forKey: "minutes") as! String
Alessandro Mattiuzzi

2

Puoi usare NSUserDefaultsrapidamente in questo modo,

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

2
La prima versione di questo post diceva di utilizzare il synchronize()comando per NSUserDefaultsper assicurarti che le tue cose vengano salvate dopo aver eseguito un blocco di modifiche. Potrebbe essere stato più necessario in iOS 7 e versioni precedenti, ma in iOS 8 e versioni successive non dovresti chiamare synchronize () nella maggior parte delle situazioni. Controlla questo per maggiori informazioni: codingexplorer.com/nsuserdefaults-a-swift-introduction
Dharmesh Kheni

2

Swift 5 e versioni successive:

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

Ho salvato NSDictionary normalmente e sono riuscito a ottenerlo correttamente.

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

// Per ottenere dati da NSDictionary.

let userDefaults = UserDefaults.standard
    let dictAddress = userDefaults.object(forKey: Constants.kAddressOfUser) as! NSDictionary

Grazie per il tuo aiuto signorina. :)
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)
            }
        }
    }
}

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:

Salva valore:

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

Valore di recupero:

let userloginid = UserDefaultHelper.userloginId

Elimina valore:

UserDefaultHelper.deleteUserLoginId()

1

Direi che la risposta di Anbu è perfettamente a posto, ma ho dovuto aggiungere guard durante il recupero delle preferenze per fare in modo che il mio programma non fallisse

Ecco il codice aggiornato in Swift 5

Archiviazione dei dati 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

    }

Recupero dei dati da 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"))
    }

0

In classe A, imposta il valore per la chiave:

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

In classe B, ottieni il valore per il testo usando la chiave dichiarata in classe Ae assegnalo alla rispettiva variabile di cui hai bisogno:

var valueOfText  = UserDefaults.value(forKey: "textValue")

0

Swift 4, ho usato Enum per gestire UserDefaults.

Questo è solo un codice di esempio. Puoi personalizzarlo secondo le tue esigenze.

Per l'archiviazione, il recupero, la rimozione. In questo modo aggiungi semplicemente una chiave per la tua chiave UserDefaults al file enum. Gestisci i valori durante il recupero e l'archiviazione in base a dataType e ai tuoi requisiti.

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

Per memorizzare un valore in userdefaults,

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

Per recuperare un valore da userdefaults,

//As AuthToken value is a string
    (UserDefaultsConstant.AuthToken.getValue() as! String)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.