Jak mogę używać UserDefaults w Swift?

119

Jak mogę używać UserDefaults do zapisywania / pobierania ciągów znaków, wartości logicznych i innych danych w Swift?

Mithun Ravindran
źródło
4
Ponownie otwieram to pytanie, ponieważ może ono służyć jako dobre ogólne pytanie na ten temat. Przyjęta odpowiedź jest również wyraźniejsza niż poprzednio zaznaczony duplikat , który również był bardziej szczegółowy niż to pytanie.
Suragch
Myślę, że to pytanie jest dostępne w przepełnieniu stosu, które powinieneś przeszukać przed dodaniem tutaj
Yogesh Patel

Odpowiedzi:

331

ref: NSUserdefault objectTypes

Swift 3 i nowsze

Sklep

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

Odzyskać

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

Usunąć

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

Usuń wszystkie klucze

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

Swift 2 i poniżej

Sklep

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

Odzyskać

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

Usunąć

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


Zarejestrować

registerDefaults: dodaje registerDictionary do ostatniej pozycji na każdej liście wyszukiwania. Oznacza to, że po tym, jak NSUserDefaults szuka wartości w każdej innej prawidłowej lokalizacji, będzie szukać zarejestrowanych wartości domyślnych, co czyni je użytecznymi jako wartość „rezerwową”. Zarejestrowane wartości domyślne nigdy nie są przechowywane między uruchomieniami aplikacji i są widoczne tylko dla aplikacji, która je rejestruje.

Domyślne wartości z domyślnych plików konfiguracyjnych zostaną automatycznie zarejestrowane.

na przykład wykryj aplikację przed uruchomieniem, utwórz strukturę do zapisania uruchamiania

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

Zarejestruj wartości domyślne podczas uruchamiania aplikacji:

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

usuń wartość po zamknięciu aplikacji:

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

}

i sprawdź stan jako

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

Nazwa pakietu UserDefaults

kolejna nazwa zestawu nieruchomości , głównie używana w koncepcji grup aplikacji , przykładowy scenariusz, który wziąłem stąd :

Przykład użycia polega na tym, że chcę oddzielić moje ustawienia UserDefault (inna logika biznesowa może wymagać oddzielnego zgrupowania ustawień UserDefault) według identyfikatora, podobnie jak SharedPreferences systemu Android. Na przykład, gdy użytkownik w mojej aplikacji kliknie przycisk wylogowania, chciałbym wyczyścić ustawienia domyślne jego konta, ale nie lokalizację urządzenia.

let user = UserDefaults(suiteName:"User")

użycie userDefaults synchronizacja , szczegółowe informacje zostały dodane w zduplikowanej odpowiedzi.

Anbu.Karthik
źródło
Kiedy i gdzie należy wywołać metody sklepu? Tuż przed zamknięciem aplikacji lub za każdym razem, gdy zmieniają się wartości?
josef
całkiem niesamowite, jedno miejsce do wszelkiego rodzaju operacji.
michaeln peterson
@ Anbu.Karthik jak zaktualizujesz wartość klucza w userdefaults?
sathya chinnasamy
2
@RajeshBaidya - userdefault zawsze przechowuje tylko ostateczną wartość
Anbu.Karthik
Czy te dane są zachowywane po instalacji / odinstalowaniu aplikacji?
OrangePot
40

Najlepszy sposób korzystania z UserDefaults

Kroki

  1. Utwórz rozszerzenie UserDefaults
  2. Utwórz wyliczenie z wymaganymi kluczami do przechowywania w lokalnym
  3. Przechowuj i pobieraj dane lokalne w dowolnym miejscu

Próba

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

wyliczenie dla kluczy używanych do przechowywania danych

enum UserDefaultsKeys : String {
    case isLoggedIn
    case userID
}

Zapisz w UserDefaults, gdzie chcesz

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

Pobieraj dane z dowolnego miejsca w aplikacji

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

Usuń wartości

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

W ten sposób możesz najlepiej przechowywać prymitywne dane

Aktualizacja Nie musisz używać funkcji synchronize () do przechowywania wartości. Jak @Moritz zwrócił uwagę na to, że jest to niepotrzebne i podał artykuł na ten temat, sprawdź komentarze, aby uzyskać więcej szczegółów

iSrinivasan27
źródło
Nie potrzebujesz synchronize(), jest to wyjaśnione w dokumentacji. Jest to nie tylko bezużyteczne, ale może spowolnić dostęp do ustawień domyślnych.
Eric Aya
Tak, jest to wymienione w dok. Po zmianie domyślnych danych zostaną one zapisane automatycznie, ale w niektórych przypadkach wartości mogą nie być przechowywane, np. Asynchroniczne. Więc pomyślałem, że lepiej jest zsynchronizować.
iSrinivasan 27
2
Nie jest lepiej - czasami jest nawet źródłem problemów. Nie używaj synchronizacji, jest przestarzała i problematyczna. Zobacz codingexplorer.com/nsuserdefaults-a-swift-introduction, w szczególności część „aktualizacja”. Przeprowadziłem również wiele testów na ten temat i usunąłem wszystkie wywołania synchronizacji we wszystkich moich aplikacjach i nigdy nie miałem problemu, nawet w tragicznych sytuacjach. Ale hej, jeśli lubisz bezużyteczne rzeczy, które mogą spowalniać twoją aplikację, zadzwoń do synchronizacji ... jasne ...;)
Eric Aya
To naprawdę pomocne. Skomentowałem sync (). Korzystanie z sync () zależy od potrzeb.
iSrinivasan 27
hii jak zapisać dane w nsuserdefaults w osobnym pliku w swift
Dilip Tiwari
15

Swift 4 :

Sklep

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

Odzyskaj

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

Usunąć

    UserDefaults.standard.removeObject(forKey:"key_name") 
Nikunj Joshi
źródło
co masz na myśli mówiąc, że ten wiersz „UserDefaults.standard.synchronize ()” jest opcjonalny? @NikunjJoshi
Nishad Arora
2
//Save
NSUserDefaults.standardUserDefaults().setObject("yourString", forKey: "YourStringKey")

//retrive
let yourStr : AnyObject? = NSUserDefaults.standardUserDefaults().objectForKey("YourStringKey")
Dharmesh Kheni
źródło
W Swift 3: let minutes = UserDefaults.standard.object (forKey: "minuty") jako! String
Alessandro Mattiuzzi
2

W NSUserDefaultsten sposób możesz szybko użyć ,

@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
źródło
2
Pierwsza wersja tego posta mówi, że używa synchronize()polecenia NSUserDefaultsdo upewnienia się, że twoje rzeczy są zapisywane po wykonaniu bloku zmian. Mogło to być bardziej konieczne w iOS 7 i wcześniejszych, ale w iOS 8 i nowszych nie powinieneś wywoływać synchronize () w większości sytuacji. Sprawdź to, aby uzyskać więcej informacji: codingexplorer.com/nsuserdefaults-a-swift-introduction
Dharmesh Kheni
2

Swift 5 i nowszy:

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
źródło
1

Zapisałem NSDictionary normalnie i udało mi się go poprawnie pobrać.

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

// Do pobierania danych z NSDictionary.

let userDefaults = UserDefaults.standard
    let dictAddress = userDefaults.object(forKey: Constants.kAddressOfUser) as! NSDictionary
Chandni
źródło
Dzięki za pomoc, panienko. :)
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
źródło
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)
 }
}

Stosowanie:

Zapisz wartość:

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

Pobierz wartość:

let userloginid = UserDefaultHelper.userloginId

Usuń wartość:

UserDefaultHelper.deleteUserLoginId()
Mannam Brahmam
źródło
1

Powiedziałbym, że odpowiedź Anbu jest w porządku, ale musiałem dodać ochronę podczas pobierania preferencji, aby mój program nie zawiódł

Oto zaktualizowany wycinek kodu w Swift 5

Przechowywanie danych w 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

    }

Pobieranie danych z 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
źródło
0

W klasie Austaw wartość klucza:

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

W klasie Bpobierz wartość dla tekstu za pomocą klucza zadeklarowanego w klasie Ai przypisz ją do odpowiedniej zmiennej, której potrzebujesz:

var valueOfText  = UserDefaults.value(forKey: "textValue")
K.Gowri Manohari
źródło
0

Swift 4, użyłem Enum do obsługi UserDefaults.

To tylko przykładowy kod. Możesz dostosować go do swoich wymagań.

Do przechowywania, pobierania, usuwania. W ten sposób po prostu dodaj klucz dla twojego klucza UserDefaults do wyliczenia. Obsługuj wartości podczas pobierania i przechowywania zgodnie z typem danych i wymaganiami.

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

Do przechowywania wartości w userdefaults,

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

Aby pobrać wartość z userdefaults,

//As AuthToken value is a string
    (UserDefaultsConstant.AuthToken.getValue() as! String)
Pramod Więcej
źródło