Comment puis-je utiliser UserDefaults dans Swift?

119

Comment puis-je utiliser UserDefaults pour enregistrer / récupérer des chaînes, des booléens et d'autres données dans Swift?

Mithun Ravindran
la source
4
Je rouvre cette question car elle peut servir de bonne question générale sur ce sujet. La réponse acceptée est également plus claire que le double précédent marqué , qui était également plus précis que cette question.
Suragch
Je pense que cette question est disponible dans le débordement de pile, vous devriez rechercher avant d'ajouter une question ici
Yogesh Patel

Réponses:

330

réf: NSUserdefault objectTypes

Swift 3 et plus

Boutique

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

Récupérer

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

Retirer

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

Supprimer toutes les clés

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

Swift 2 et inférieur

Boutique

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

Récupérer

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

Retirer

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


S'inscrire

registerDefaults: ajoute le registrationDictionary au dernier élément de chaque liste de recherche. Cela signifie qu'après que NSUserDefaults a recherché une valeur dans tous les autres emplacements valides, il cherchera dans les valeurs par défaut enregistrées, ce qui les rendra utiles comme valeur de «secours». Les valeurs par défaut enregistrées ne sont jamais stockées entre les exécutions d'une application et ne sont visibles que par l'application qui les enregistre.

Les valeurs par défaut des fichiers de configuration par défaut seront automatiquement enregistrées.

par exemple détecter l'application depuis le lancement, créer la structure pour enregistrer le lancement

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

Enregistrez les valeurs par défaut au lancement de l'application:

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

supprimez la valeur lors de l'arrêt de l'application:

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

}

et vérifiez la condition comme

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

Nom de la suite UserDefaults

un autre nom de suite de propriétés , principalement utilisé pour le concept de groupes d'applications , l'exemple de scénario que j'ai pris ici :

Le cas d'utilisation est que je souhaite séparer mes UserDefaults (une logique métier différente peut exiger que les Userdefaults soient groupés séparément) par un identifiant, tout comme les SharedPreferences d'Android. Par exemple, lorsqu'un utilisateur de mon application clique sur le bouton de déconnexion, je souhaite effacer les paramètres par défaut de son compte, mais pas l'emplacement de l'appareil.

let user = UserDefaults(suiteName:"User")

utilisation de userDefaults synchronize , les informations détaillées ont été ajoutées dans la réponse en double.

Anbu.Karthik
la source
Quand et où devez-vous appeler les méthodes du magasin? Juste avant la fermeture de l'application ou à chaque fois que les valeurs changent?
josef
assez génial, un seul endroit pour toutes sortes d'opérations.
Michaeln Peterson
@ Anbu.Karthik comment allez-vous mettre à jour la valeur d'une clé dans userdefaults?
sathya chinnasamy
2
@RajeshBaidya - userdefault stocke toujours la valeur finale uniquement
Anbu.Karthik
Ces données persistent-elles pendant l'installation / la désinstallation de l'application?
OrangePot
40

Meilleure façon d'utiliser UserDefaults

Pas

  1. Créer une extension de UserDefaults
  2. Créer une énumération avec les clés requises pour stocker en local
  3. Stockez et récupérez les données locales où vous le souhaitez

Échantillon

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 pour les clés utilisées pour stocker des données

enum UserDefaultsKeys : String {
    case isLoggedIn
    case userID
}

Enregistrer dans UserDefaults où vous le souhaitez

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

Récupérez des données n'importe où dans l'application

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

Supprimer les valeurs

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

De cette façon, vous pouvez stocker les données primitives au mieux

Mise à jour Vous n'avez pas besoin d'utiliser synchronize () pour stocker les valeurs. Comme @Moritz l'a souligné, il est inutile et donné l'article à ce sujet.Vérifiez les commentaires pour plus de détails

iSrinivasan27
la source
Vous n'en avez pas besoin synchronize(), c'est expliqué dans la documentation. Ce n'est pas seulement inutile ici, mais cela pourrait ralentir l'accès aux valeurs par défaut.
Eric Aya
Oui, c'est mentionné dans le doc. Une fois que les données par défaut sont modifiées, elles seront enregistrées automatiquement mais dans certains cas, vos valeurs peuvent ne pas être stockées, c'est-à-dire asynchrones. J'ai donc pensé qu'il valait mieux synchroniser.
iSrinivasan 27
2
Ce n'est pas mieux - c'est même parfois la source de problèmes. N'utilisez pas la synchronisation, elle est obsolète et problématique. Voir codingexplorer.com/nsuserdefaults-a-swift-introduction notamment la partie "mise à jour". J'ai également effectué de nombreux tests à ce sujet et supprimé tous les appels à synchroniser dans toutes mes applications et je n'ai jamais eu de problème, même dans des situations difficiles. Mais bon, si vous aimez les trucs inutiles qui peuvent ralentir votre application, appelez la synchronisation ... bien sûr ...;)
Eric Aya
C'est vraiment utile. J'ai commenté sync (). L'utilisation de sync () est basée sur les besoins.
iSrinivasan 27
hii comment enregistrer des données dans nsuserdefaults dans un fichier séparé dans swift
Dilip Tiwari
15

Swift 4 :

Boutique

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

Retrive

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

Retirer

    UserDefaults.standard.removeObject(forKey:"key_name") 
Nikunj Joshi
la source
qu'entendez-vous par cette ligne «UserDefaults.standard.synchronize ()» en option? @NikunjJoshi
Nishad Arora
2
//Save
NSUserDefaults.standardUserDefaults().setObject("yourString", forKey: "YourStringKey")

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

Vous pouvez utiliser NSUserDefaultsrapidement de cette façon,

@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
la source
2
La première version de cet article indiquait d'utiliser la synchronize()commande pour NSUserDefaultspour vous assurer que vos données sont enregistrées après avoir effectué un bloc de modifications. Cela aurait peut-être été plus nécessaire dans iOS 7 et versions antérieures, mais dans iOS 8 et versions ultérieures, vous ne devriez pas appeler synchronize () dans la plupart des situations. Vérifiez ceci pour plus d'informations: codingexplorer.com/nsuserdefaults-a-swift-introduction
Dharmesh Kheni
2

Swift 5 et supérieur:

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
la source
1

J'ai sauvegardé NSDictionary normalement et j'ai pu l'obtenir correctement.

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

// Pour obtenir des données de NSDictionary.

let userDefaults = UserDefaults.standard
    let dictAddress = userDefaults.object(forKey: Constants.kAddressOfUser) as! NSDictionary
Chandni
la source
Merci pour votre aide mademoiselle. :)
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
la source
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)
 }
}

Usage:

Enregistrer la valeur:

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

Récupérer la valeur:

let userloginid = UserDefaultHelper.userloginId

Supprimer la valeur:

UserDefaultHelper.deleteUserLoginId()
Mannam Brahmam
la source
1

Je dirais que la réponse d'Anbu est parfaitement correcte mais j'ai dû ajouter une garde lors de la récupération des préférences pour que mon programme n'échoue pas

Voici l'extrait de code mis à jour dans Swift 5

Stockage des données dans 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

    }

Récupération des données depuis 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
la source
0

En classe A, définissez la valeur de la clé:

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

En classe B, récupérez la valeur du texte à l'aide de la clé déclarée en classe Aet affectez-la à la variable respective dont vous avez besoin:

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

Swift 4, j'ai utilisé Enum pour gérer UserDefaults.

Ceci est juste un exemple de code. Vous pouvez le personnaliser selon vos besoins.

Pour le stockage, la récupération, la suppression. De cette façon, ajoutez simplement une clé pour votre clé UserDefaults à l'énumération. Gérez les valeurs lors de l'obtention et du stockage en fonction de dataType et de vos besoins.

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

Pour stocker une valeur dans userdefaults,

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

Pour récupérer une valeur à partir de userdefaults,

//As AuthToken value is a string
    (UserDefaultsConstant.AuthToken.getValue() as! String)
Pramod Plus
la source