NSUserDefaults — vad är det, UserDefaults API och arbete med iOS-inställningar

Författare: IT Sectr Publicerad: 2026-03-12 Lästid: 10 min

NSUserDefaults är en nyckel-värde datalagring i iOS, watchOS, tvOS och macOS, avsedd för att spara appens inställningar och konfigurationer. Data lagras i en plist-fil i appens sandlåda och synkroniseras automatiskt med iCloud via NSUbiquitousKeyValueStore. Enligt officiell dokumentation Apple Developer, 2025, stöder NSUserDefaults lagring av primitiva typer: String, Int, Bool, Float, Double, Data, Date, Array och Dictionary. Klassen har bytt namn till UserDefaults från och med Swift 3, men dess Objective-C-namn NSUserDefaults förblir allmänt använt i kodbasen och Apples dokumentation.

Huvudpunkter

  • NSUserDefaults — nyckel-värde lagring på iOS och macOS för att spara enkla appinställningar i en plist-fil.
  • Stöder nio datatyper: String, Int, Bool, Float, Double, Data, Date, Array och Dictionary.
  • Data synkroniseras automatiskt med iCloud via NSUbiquitousKeyValueStore med utvecklarens stöd.
  • Använder ett system av register (domäner) med kaskadsökning av värde över domänkedjan.
  • För lagring av känslig data rekommenderar Apple att använda Keychain istället för NSUserDefaults.

Vad är NSUserDefaults?

NSUserDefaults (UserDefaults i Swift) är en inbyggd Apple-mekanism för att lagra nyckel-värde-par i plist-format. Den är tillgänglig på alla Apple-plattformar: iOS, iPadOS, watchOS, tvOS och macOS. Huvudsyftet är att spara användarpreferenser, gränssnittstillstånd, första-start-flaggor, valda alternativ och andra enkla data som överlever en omstart av appen.

Varje iOS-app har en isolerad sandlåda och NSUserDefaults lagras i katalogen Library/Preferences i denna sandlåda i en fil med namnet Bundle Identifier. Plist-filen innehåller nyckel-värde-par, där nyckeln är en sträng och värdet är en av de typer som stöds. Filstorleken är inte begränsad, men Apple rekommenderar att endast inställningar lagras i UserDefaults, inte stora datamängder.

Från och med iOS 8 stöder NSUserDefaults App Groups — delad lagring mellan appar från samma utvecklare och deras tillägg (widgetar, watchOS medföljande appar). För detta används initialiseraren init?(suiteName:) med App Group-identifieraren. Detta gör det möjligt för en widget på Today-skärmen att läsa inställningar från huvudappen utan att duplicera lagringslogik.

Lagringsformat: plist på enheten

Fysiskt lagras NSUserDefaults i en binär plist-fil på sökvägen: {Sandbox}/Library/Preferences/com.example.myapp.plist. Filen använder binärt plist-format (NSPropertyListBinaryFormat_v1_0) för kompakthet och läshastighet. På macOS kan filen vara i XML-format för kompatibilitet. Till skillnad från SharedPreferences på Android kan UserDefaults plist-filer innehålla nästlade strukturer via Dictionary och Array.

NSUserDefaults-filer är inte krypterade som standard. Data lagras i öppen form och kan läsas vid fysisk åtkomst till enheten eller via säkerhetskopia. För lagring av känslig data (lösenord, tokens, krypteringsnycklar) rekommenderar Apple starkt att använda Keychain, som automatiskt krypterar data på operativsystemsnivå.

Hur fungerar NSUserDefaults i iOS

NSUserDefaults fungerar enligt principen om cachning i minnet med periodisk synkronisering till disk. Vid första åtkomst till standardinstansen UserDefaults.standard laddar systemet plist-filen i RAM-minnet som en Dictionary. Alla efterföljande läsningar görs från minnet. Skrivning sker också först i minnet, och synkronisering till disk sker periodiskt i bakgrunden.

Skrivoperationer använder metoden set(_:forKey:), som tar ett valfritt värde av typen Any?. Värdet kan vara nil — för att ta bort en nyckel. För omedelbar skrivning till disk användes tidigare metoden synchronize(), men från och med iOS 7 och OS X 10.9 krävs den inte längre — systemet synkroniserar automatiskt data med jämna mellanrum. Apple har officiellt förklarat synchronize() överflödig i sin dokumentation.

UserDefaults-register och domäner

NSUserDefaults använder ett system av register (domäner) för att organisera sökning efter värden. När appen begär ett värde baserat på en nyckel kontrollerar UserDefaults successivt domänerna i en viss ordning: först NSArgumentDomain (kommandoradsargument), sedan applikationsdomänen (Application), sedan NSGlobalDomain (systeminställningar), sedan språkspecifika domäner och slutligen NSRegistrationDomain (standardvärden registrerade via register(defaults:)).

swift
import Foundation

// Standard UserDefaults-instans
let defaults = UserDefaults.standard

// Skriva värden
defaults.set("Anna Petrova", forKey: "username")
defaults.set(28, forKey: "age")
defaults.set(true, forKey: "isLoggedIn")

// Registrering av standardvärden
defaults.register(defaults: [
    "theme": "system",
    "fontSize": 14
])

// Läsa med returnering av standardvärde
let theme = defaults.string(forKey: "theme") ?? "system"
let fontSize = defaults.integer(forKey: "fontSize")

Domänen NSRegistrationDomain är en programdomän som endast finns i RAM-minnet och inte sparas på disken. Den används för att ställa in standardvärden som är aktiva tills appen skriver sitt eget värde i applikationsdomänen. Detta gör det möjligt att skapa en enda konfigurationspunkt för standardinställningar som kan ändras centralt under utvecklingsfasen.

Huvudmetoder för NSUserDefaults

NSUserDefaults tillhandahåller en uppsättning typade metoder för att läsa och skriva data: string(forKey:), integer(forKey:), bool(forKey:), float(forKey:), double(forKey:), data(forKey:), array(forKey:), dictionary(forKey:) och object(forKey:). Varje läshar metod har en motsvarande skrivmetod set(_:forKey:) med automatisk bestämning av typen för det lagrade värdet. Swift-versionen av UserDefaults använder strikt typning, men Objective-C-versionen accepterar och returnerar id.

Läsmetod (Swift)DatatypStandardvärde
string(forKey:)String?nil
integer(forKey:)Int0
bool(forKey:)Boolfalse
float(forKey:)Float0.0
double(forKey:)Double0.0
data(forKey:)Data?nil

synchronize och dess aktualitet

Metoden synchronize() i NSUserDefaults tvingar fram skrivning av alla ändringar från minnet till disken. I tidiga versioner av iOS var denna metod tvungen att anropas efter varje skrivning för att garantera datalagring. Från och med iOS 7 synkroniserar systemet automatiskt UserDefaults i bakgrunden, och Apple har officiellt förklarat synchronize() överflödig. Anrop av denna metod orsakar inte ett fel, men ger inga ytterligare garantier för lagring.

För att övervaka ändringar tillhandahåller NSUserDefaults notifikationen UserDefaults.didChangeNotification och KVO-observationsmetoden addObserver(_:forKeyPath:options:context:). I SwiftUI finns Property Wrapper @AppStorage, som automatiskt synkroniserar värdet i UserDefaults med UI-uppdateringar. @AppStorage stöder samma typer som UserDefaults och är det föredragna sättet att arbeta med inställningar i SwiftUI-appar.

swift
// Observera ändringar via KVO
class SettingsViewModel: NSObject {
    override func observeValue(
        forKeyPath keyPath: String?,
        of object: Any?,
        change: [NSKeyValueChangeKey: Any]?,
        context: UnsafeMutableRawPointer?
    ) {
        guard let keyPath else { return }
        print("Nyckel ändrad: \(keyPath)")
    }
}

// SwiftUI - AppStorage
struct SettingsView: View {
    @AppStorage("theme") private var theme: String = "system"

    var body: some View {
        Picker("Tema", selection: $theme) {
            Text("System").tag("system")
            Text("Ljus").tag("light")
            Text("Mörk").tag("dark")
        }
    }
}

För arbete med App Groups (delad lagring mellan app och tillägg) används initialiseraren UserDefaults(suiteName:) med App Group-identifieraren. Till exempel, "group.com.example.myapp". Data som skrivs till denna instans är tillgänglig från huvudappen, widgeten, watchOS-medföljande appen och andra tillägg som tillhör samma App Group. Varje suite-instans lagras i en separat plist-fil.

NSUserDefaults vs lagringsalternativ

Trots bekvämligheten och enkelheten är NSUserDefaults inte en universell lagring för alla datatyper på iOS. Beroende på volym, kritikalitet och säkerhetskrav tillhandahåller Apple flera alternativ, var och en optimerad för ett specifikt användningsscenario.

LösningNär ska användasBegränsningar
NSUserDefaultsGränssnittsinställningar och konfigurationInte lämpligt för stora data och hemligheter
KeychainLösenord, tokens, krypteringsnycklarMer komplicerat att använda, långsammare
CoreDataStrukturerad data med relationerÖverdrivet för 10-20 inställningar
FileManagerDokument, bilder, binär dataKräver manuell filhantering
CloudKitMolnsynkronisering mellan enheterKräver iCloud-konto och nätverksanslutning

Keychain — säker lagring

Keychain är en skyddad Apple-lagring för konfidentiell data. Till skillnad från NSUserDefaults krypteras all data i Keychain på operativsystemsnivå med hjälp av Secure Enclave-hårdvarukryptering på kompatibla enheter. Keychain låses och låses upp automatiskt tillsammans med enheten och stöder delning av åtkomst mellan appar från samma utvecklare via Keychain Access Groups.

Den största nackdelen med Keychain är API:ets komplexitet. För att enkelt lagra en sträng måste en SecItemAdd-förfrågan skapas med angivande av attribut: klass (kSecClassGenericPassword), tjänst (kSecAttrService), konto (kSecAttrAccount) och själva data (kSecValueData). För att förenkla arbetet med Keychain finns tredjepartsomslag som KeychainAccess och SwiftKeychainWrapper, som ger ett bekvämt nyckel-värde-gränssnitt liknande UserDefaults.

Exempel på användning av NSUserDefaults i Swift

Låt oss titta på ett praktiskt exempel: spara och återställa onboarding-status (välkomstskärmar) i en iOS-app med NSUserDefaults. Vid första start ser användaren onboarding-skärmarna, efter att ha gått igenom dem sparas en flagga i UserDefaults. Vid efterföljande starter hoppas onboarding över. För SwiftUI används @AppStorage, för UIKit — direkt åtkomst till UserDefaults.standard.

Spara onboarding-status

Låt oss skapa en hanterare OnboardingManager som kapslar in arbetet med UserDefaults för att lagra onboarding-status. Hanteraren tillhandahåller egenskapen isOnboardingCompleted för att kontrollera status och metoden markOnboardingCompleted för att ställa in flaggan. Lagringsnyckeln har placerats i en konstant för att förhindra stavfel. För enhetstestning använder hanteraren protokollet UserDefaultsProtocol, vilket gör det möjligt att ersätta den verkliga lagringen med MockUserDefaults.

swift
class OnboardingManager {
    private let defaults: UserDefaults
    private let hasSeenKey = "has_seen_onboarding"

    init(defaults: UserDefaults = .standard) {
        self.defaults = defaults
    }

    var isOnboardingCompleted: Bool {
        defaults.bool(forKey: hasSeenKey)
    }

    func markOnboardingCompleted() {
        defaults.set(true, forKey: hasSeenKey)
    }

    func resetOnboarding() {
        defaults.removeObject(forKey: hasSeenKey)
    }
}

// Användning i appen
let onboardingManager = OnboardingManager()
if !onboardingManager.isOnboardingCompleted {
    showOnboarding()
} else {
    showMainScreen()
}

För lagring av mer komplexa inställningar, som ett strukturerat Profile-objekt, rekommenderas användning av Codable-protokollet och JSONEncoder/JSONDecoder. Objektet serialiseras till Data via JSONEncoder, sparas via set(_:forKey:), och vid läsning deserialiseras det från Data tillbaka till objekt via JSONDecoder. Detta tillvägagångssätt gör det möjligt att lagra komplexa strukturer i UserDefaults utan förlust av typsäkerhet.

swift
struct UserProfile: Codable {
    let name: String
    let age: Int
    let preferences: [String: String]
}

extension UserDefaults {
    func save<T: Codable>(_ value: T, forKey key: String) {
        if let data = try? JSONEncoder().encode(value) {
            set(data, forKey: key)
        }
    }

    func load<T: Codable>(_ type: T.Type, forKey key: String) -> T? {
        guard let data = data(forKey: key) else { return nil }
        return try? JSONDecoder().decode(type, from: data)
    }
}

// Användning
let profile = UserProfile(name: "Anna", age: 28, preferences: ["theme": "dark"])
UserDefaults.standard.save(profile, forKey: "user_profile")
let loaded = UserDefaults.standard.load(UserProfile.self, forKey: "user_profile")

Det är viktigt att komma ihåg att NSUserDefaults inte är avsett för lagring av stora datamängder. Apple rekommenderar att begränsa storleken på lagrad data till några tiotals kilobyte. För lagring av stora objekt (bilder, dokument, serialiserade modeller) bör FileManager med Documents-katalogen eller CoreData användas. Dessutom stöder UserDefaults inte versionshantering av dataschemat — när strukturen för en Codable-modell ändras kan gamla data inte deserialiseras, och detta måste hanteras i appkoden.

Vanliga frågor

Vad skiljer NSUserDefaults från SharedPreferences på Android?

Båda är nyckel-värde-lager, men NSUserDefaults stöder fler typer (Data, Date, Array, Dictionary) och synkroniseras automatiskt med iCloud. SharedPreferences lagrar data i XML, NSUserDefaults i plist-format. NSUserDefaults har ett domänsystem med kaskadsökning, SharedPreferences använder en enkel platt struktur med filnamn.

Är det säkert att lagra lösenord i NSUserDefaults?

Nej, NSUserDefaults lagrar data i öppen form utan kryptering. För lösenord, tokens och krypteringsnycklar, använd Keychain som krypterar data på Secure Enclave-nivå. Keychain stöder även åtkomstattribut som biometrisk autentisering (Face ID / Touch ID) innan hemligheten läses.

Hur synkroniserar jag NSUserDefaults mellan enheter?

För synkronisering mellan enheter av samma användare, använd NSUbiquitousKeyValueStore — iClouds molnbaserade nyckel-värde-lager. Data som skrivs till denna tjänst på en enhet visas automatiskt på alla andra enheter med samma iCloud-konto. Maximal volym — 1 MB per app, 1024 nycklar.

Hur tar jag bort all data från NSUserDefaults?

För att ta bort all data, anropa metoden removePersistentDomain(forName:) med appens Bundle Identifier. För att ta bort enskilda värden, använd removeObject(forKey:). För fullständig återställning av appinställningar: UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!). Alla borttagningar tillämpas omedelbart på minnescachen.

Vad är den maximala datastorleken i NSUserDefaults?

Apple sätter ingen strikt gräns för storleken på NSUserDefaults, men det rekommenderas att inte överstiga 100 KB för den totala volymen av all lagrad data. För stora volymer, använd CoreData eller FileManager. Vid lagring av mer än 1 MB data kan läsprestandan vid appstart märkbart minska.

Sammanfattning

  • NSUserDefaults — inbyggd Apple nyckel-värde-lagring för enkla appinställningar i plist-format.
  • Stöder nio datatyper: String, Int, Bool, Float, Double, Data, Date, Array och Dictionary.
  • Använder ett domänsystem med kaskadsökning via NSRegistrationDomain, NSGlobalDomain och applikationsdomänen.
  • För synkronisering mellan enheter tillhandahåller Apple NSUbiquitousKeyValueStore med en gräns på 1 MB per app.
  • För säkerhet, använd Keychain för lösenord och tokens, inte NSUserDefaults.
  • I SwiftUI är det föredragna arbetssättet Property Wrapper @AppStorage med automatisk UI-synkronisering.
  • För stora eller strukturerade data, välj CoreData eller FileManager istället för NSUserDefaults.

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också