NSUserDefaults — τι είναι, UserDefaults API και εργασία με ρυθμίσεις iOS

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-03-12 Χρόνος ανάγνωσης: 10 λεπ

Το NSUserDefaults είναι ένας χώρος αποθήκευσης δεδομένων κλειδιού-τιμής σε iOS, watchOS, tvOS και macOS, που προορίζεται για την αποθήκευση ρυθμίσεων και παραμέτρων της εφαρμογής. Τα δεδομένα αποθηκεύονται σε ένα αρχείο plist στο sandbox της εφαρμογής και συγχρονίζονται αυτόματα με το iCloud μέσω του NSUbiquitousKeyValueStore. Σύμφωνα με την επίσημη τεκμηρίωση Apple Developer, 2025, το NSUserDefaults υποστηρίζει την αποθήκευση αρχέγονων τύπων: String, Int, Bool, Float, Double, Data, Date, Array και Dictionary. Η κλάση μετονομάστηκε σε UserDefaults από το Swift 3, αλλά το όνομά της Objective-C NSUserDefaults παραμένει ευρέως χρησιμοποιούμενο στη βάση κώδικα και στην τεκμηρίωση της Apple.

Κύρια Σημεία

  • NSUserDefaults — χώρος αποθήκευσης κλειδιού-τιμής σε iOS και macOS για αποθήκευση απλών ρυθμίσεων εφαρμογής σε αρχείο plist.
  • Υποστηρίζει εννέα τύπους δεδομένων: String, Int, Bool, Float, Double, Data, Date, Array και Dictionary.
  • Τα δεδομένα συγχρονίζονται αυτόματα με το iCloud μέσω του NSUbiquitousKeyValueStore με υποστήριξη από τον προγραμματιστή.
  • Χρησιμοποιεί σύστημα μητρώων (τομέων) με αναζήτηση σε αλληλουχία κατά μήκος της αλυσίδας τομέων.
  • Για την αποθήκευση ευαίσθητων δεδομένων, η Apple συνιστά τη χρήση του Keychain αντί του NSUserDefaults.

Τι είναι το NSUserDefaults;

Το NSUserDefaults (UserDefaults σε Swift) είναι ένας ενσωματωμένος μηχανισμός της Apple για την αποθήκευση ζευγών κλειδιού-τιμής σε μορφή plist. Είναι διαθέσιμος σε όλες τις πλατφόρμες Apple: iOS, iPadOS, watchOS, tvOS και macOS. Κύριος σκοπός — αποθήκευση προτιμήσεων χρήστη, κατάστασης διεπαφής, σημαιών πρώτης εκκίνησης, επιλεγμένων επιλογών και άλλων απλών δεδομένων που επιβιώνουν από την επανεκκίνηση της εφαρμογής.

Κάθε εφαρμογή iOS έχει ένα απομονωμένο sandbox, και το NSUserDefaults αποθηκεύεται στον κατάλογο Library/Preferences μέσα σε αυτό το sandbox σε ένα αρχείο με το όνομα Bundle Identifier. Το αρχείο plist περιέχει ζεύγη κλειδιού-τιμής, όπου το κλειδί είναι μια συμβολοσειρά και η τιμή είναι ένας από τους υποστηριζόμενους τύπους. Το μέγεθος του αρχείου δεν είναι περιορισμένο, αλλά η Apple συνιστά την αποθήκευση μόνο ρυθμίσεων στο UserDefaults, όχι μεγάλων όγκων δεδομένων.

Από το iOS 8, το NSUserDefaults υποστηρίζει τα App Groups — κοινόχρηστο χώρο αποθήκευσης μεταξύ εφαρμογών του ίδιου προγραμματιστή και των επεκτάσεών τους (widget, watchOS συνοδευτικές εφαρμογές). Για αυτό χρησιμοποιείται ο αρχικοποιητής init?(suiteName:) με το αναγνωριστικό App Group. Αυτό επιτρέπει, για παράδειγμα, σε ένα widget στην οθόνη Today να διαβάζει ρυθμίσεις από την κύρια εφαρμογή χωρίς διπλασιασμό της λογικής αποθήκευσης.

Μορφή αποθήκευσης: plist στη συσκευή

Φυσικά, το NSUserDefaults αποθηκεύεται σε ένα δυαδικό αρχείο plist στη διαδρομή: {Sandbox}/Library/Preferences/com.example.myapp.plist. Το αρχείο χρησιμοποιεί τη δυαδική μορφή plist (NSPropertyListBinaryFormat_v1_0) για συμπαγή και ταχύτητα ανάγνωσης. Σε macOS, το αρχείο μπορεί να είναι σε μορφή XML για συμβατότητα. Σε αντίθεση με το SharedPreferences στο Android, τα αρχεία plist του UserDefaults μπορούν να περιέχουν ένθετες δομές μέσω Dictionary και Array.

Τα αρχεία NSUserDefaults δεν είναι κρυπτογραφημένα από προεπιλογή. Τα δεδομένα αποθηκεύονται σε ανοιχτή μορφή και μπορούν να διαβαστούν με φυσική πρόσβαση στη συσκευή ή μέσω αντιγράφου ασφαλείας. Για την αποθήκευση ευαίσθητων δεδομένων (κωδικοί πρόσβασης, διακριτικά, κλειδιά κρυπτογράφησης), η Apple συνιστά κατηγορηματικά τη χρήση του Keychain, το οποίο κρυπτογραφεί αυτόματα δεδομένα σε επίπεδο λειτουργικού συστήματος.

Πώς λειτουργεί το NSUserDefaults στο iOS

Το NSUserDefaults λειτουργεί με βάση την αρχή της προσωρινής αποθήκευσης στη μνήμη με περιοδικό συγχρονισμό στο δίσκο. Κατά την πρώτη πρόσβαση στο τυπικό στιγμιότυπο UserDefaults.standard, το σύστημα φορτώνει το αρχείο plist στη μνήμη RAM με τη μορφή Dictionary. Όλες οι επόμενες αναγνώσεις γίνονται από τη μνήμη. Η εγγραφή γίνεται επίσης πρώτα στη μνήμη, και ο συγχρονισμός στο δίσκο γίνεται περιοδικά στο παρασκήνιο.

Οι λειτουργίες εγγραφής χρησιμοποιούν τη μέθοδο set(_:forKey:), η οποία δέχεται μια προαιρετική τιμή τύπου Any?. Η τιμή μπορεί να είναι nil — για διαγραφή του κλειδιού. Για άμεση εγγραφή στο δίσκο χρησιμοποιούνταν προηγουμένως η μέθοδος synchronize(), αλλά από το iOS 7 και OS X 10.9 δεν απαιτείται πλέον — το σύστημα συγχρονίζει αυτόματα δεδομένα σε τακτά χρονικά διαστήματα. Η Apple έχει επίσημα δηλώσει το synchronize() ως περιττό στην τεκμηρίωσή της.

Μητρώα UserDefaults και τομείς

Το NSUserDefaults χρησιμοποιεί ένα σύστημα μητρώων (τομέων) για την οργάνωση της αναζήτησης τιμών. Όταν η εφαρμογή ζητά μια τιμή βάσει κλειδιού, το UserDefaults ελέγχει διαδοχικά τους τομείς με συγκεκριμένη σειρά: πρώτα NSArgumentDomain (ορίσματα γραμμής εντολών), μετά τον τομέα εφαρμογής (Application), στη συνέχεια NSGlobalDomain (ρυθμίσεις συστήματος), έπειτα τομείς ειδικούς για γλώσσα και τέλος NSRegistrationDomain (προεπιλεγμένες τιμές που καταχωρήθηκαν μέσω register(defaults:)).

swift
import Foundation

// Τυπικό στιγμιότυπο UserDefaults
let defaults = UserDefaults.standard

// Εγγραφή τιμών
defaults.set("Άννα Πέτροβα", forKey: "username")
defaults.set(28, forKey: "age")
defaults.set(true, forKey: "isLoggedIn")

// Καταχώρηση προεπιλεγμένων τιμών
defaults.register(defaults: [
    "theme": "system",
    "fontSize": 14
])

// Ανάγνωση με επιστροφή προεπιλεγμένης τιμής
let theme = defaults.string(forKey: "theme") ?? "system"
let fontSize = defaults.integer(forKey: "fontSize")

Ο τομέας NSRegistrationDomain είναι ένας τομέας λογισμικού που υπάρχει μόνο στη μνήμη RAM και δεν αποθηκεύεται στο δίσκο. Χρησιμοποιείται για τον καθορισμό προεπιλεγμένων τιμών που είναι ενεργές έως ότου η εφαρμογή γράψει τη δική της τιμή στον τομέα εφαρμογής. Αυτό επιτρέπει τη δημιουργία ενός ενιαίου σημείου παραμετροποίησης για προεπιλεγμένες ρυθμίσεις που μπορούν να αλλάζονται κεντρικά στη φάση ανάπτυξης.

Κύριες μέθοδοι του NSUserDefaults

Το NSUserDefaults παρέχει ένα σύνολο τυποποιημένων μεθόδων για ανάγνωση και εγγραφή δεδομένων: string(forKey:), integer(forKey:), bool(forKey:), float(forKey:), double(forKey:), data(forKey:), array(forKey:), dictionary(forKey:) και object(forKey:). Κάθε μέθοδος ανάγνωσης έχει μια αντίστοιχη μέθοδο εγγραφής set(_:forKey:) με αυτόματο προσδιορισμό του τύπου της αποθηκευμένης τιμής. Η έκδοση Swift του UserDefaults χρησιμοποιεί αυστηρή τυποποίηση, αλλά η έκδοση Objective-C δέχεται και επιστρέφει id.

Μέθοδος ανάγνωσης (Swift)Τύπος δεδομένωνΠροεπιλεγμένη τιμή
string(forKey:)String?nil
integer(forKey:)Int0
bool(forKey:)Boolfalse
float(forKey:)Float0.0
double(forKey:)Double0.0
data(forKey:)Data?nil

synchronize και η επικαιρότητά του

Η μέθοδος synchronize() στο NSUserDefaults εξαναγκάζει την εγγραφή όλων των αλλαγών από τη μνήμη στο δίσκο. Στις πρώιμες εκδόσεις iOS, αυτή η μέθοδος έπρεπε να καλείται μετά από κάθε εγγραφή για την εγγύηση αποθήκευσης δεδομένων. Από το iOS 7, το σύστημα συγχρονίζει αυτόματα το UserDefaults στο παρασκήνιο, και η Apple έχει επίσημα δηλώσει το synchronize() ως περιττό. Η κλήση αυτής της μεθόδου δεν προκαλεί σφάλμα, αλλά δεν παρέχει καμία πρόσθετη εγγύηση αποθήκευσης.

Για την παρακολούθηση αλλαγών, το NSUserDefaults παρέχει την ειδοποίηση UserDefaults.didChangeNotification και τη μέθοδο παρατήρησης KVO addObserver(_:forKeyPath:options:context:). Στο SwiftUI είναι διαθέσιμο το Property Wrapper @AppStorage, το οποίο συγχρονίζει αυτόματα την τιμή στο UserDefaults με την ενημέρωση UI. Το @AppStorage υποστηρίζει τους ίδιους τύπους με το UserDefaults και είναι ο προτιμώμενος τρόπος εργασίας με ρυθμίσεις σε εφαρμογές SwiftUI.

swift
// Παρατήρηση αλλαγών μέσω KVO
class SettingsViewModel: NSObject {
    override func observeValue(
        forKeyPath keyPath: String?,
        of object: Any?,
        change: [NSKeyValueChangeKey: Any]?,
        context: UnsafeMutableRawPointer?
    ) {
        guard let keyPath else { return }
        print("Το κλειδί άλλαξε: \(keyPath)")
    }
}

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

    var body: some View {
        Picker("Θέμα", selection: $theme) {
            Text("Σύστημα").tag("system")
            Text("Φωτεινό").tag("light")
            Text("Σκοτεινό").tag("dark")
        }
    }
}

Για εργασία με App Groups (κοινόχρηστος χώρος αποθήκευσης μεταξύ εφαρμογής και επεκτάσεων) χρησιμοποιείται ο αρχικοποιητής UserDefaults(suiteName:) με το αναγνωριστικό App Group. Για παράδειγμα, "group.com.example.myapp". Τα δεδομένα που γράφονται σε αυτό το στιγμιότυπο είναι προσβάσιμα από την κύρια εφαρμογή, το widget, τη συνοδευτική εφαρμογή watchOS και άλλες επεκτάσεις που ανήκουν στο ίδιο App Group. Κάθε στιγμιότυπο suite αποθηκεύεται σε ξεχωριστό αρχείο plist.

NSUserDefaults vs εναλλακτικές αποθήκευσης

Παρά την ευκολία και την απλότητα, το NSUserDefaults δεν είναι ένας καθολικός χώρος αποθήκευσης για όλους τους τύπους δεδομένων στο iOS. Ανάλογα με τον όγκο, την κρισιμότητα και τις απαιτήσεις ασφαλείας, η Apple παρέχει πολλές εναλλακτικές, καθεμία βελτιστοποιημένη για ένα συγκεκριμένο σενάριο χρήσης.

ΛύσηΠότε να χρησιμοποιείταιΠεριορισμοί
NSUserDefaultsΡυθμίσεις διεπαφής και παραμετροποίησηΔεν είναι κατάλληλο για μεγάλα δεδομένα και μυστικά
KeychainΚωδικοί πρόσβασης, διακριτικά, κλειδιά κρυπτογράφησηςΠιο περίπλοκο στη χρήση, πιο αργό
CoreDataΔομημένα δεδομένα με σχέσειςΥπερβολικό για 10-20 ρυθμίσεις
FileManagerΈγγραφα, εικόνες, δυαδικά δεδομέναΑπαιτεί χειροκίνητη διαχείριση αρχείων
CloudKitΣυγχρονισμός cloud μεταξύ συσκευώνΑπαιτεί λογαριασμό iCloud και σύνδεση δικτύου

Keychain — ασφαλής αποθήκευση

Το Keychain είναι ένας προστατευμένος χώρος αποθήκευσης της Apple για εμπιστευτικά δεδομένα. Σε αντίθεση με το NSUserDefaults, όλα τα δεδομένα στο Keychain είναι κρυπτογραφημένα σε επίπεδο λειτουργικού συστήματος χρησιμοποιώντας υλική κρυπτογράφηση Secure Enclave σε συμβατές συσκευές. Το Keychain κλειδώνεται και ξεκλειδώνεται αυτόματα μαζί με τη συσκευή και υποστηρίζει διαμοιρασμό πρόσβασης μεταξύ εφαρμογών του ίδιου προγραμματιστή μέσω Keychain Access Groups.

Το κύριο μειονέκτημα του Keychain είναι η πολυπλοκότητα του API. Για απλή αποθήκευση μιας συμβολοσειράς, πρέπει να δημιουργηθεί ένα αίτημα SecItemAdd με καθορισμό χαρακτηριστικών: κλάσης (kSecClassGenericPassword), υπηρεσίας (kSecAttrService), λογαριασμού (kSecAttrAccount) και των ίδιων των δεδομένων (kSecValueData). Για απλοποίηση της εργασίας με το Keychain, υπάρχουν περιτυλίγματα τρίτων, όπως τα KeychainAccess και SwiftKeychainWrapper, που παρέχουν μια βολική διεπαφή κλειδιού-τιμής παρόμοια με το UserDefaults.

Παράδειγμα χρήσης του NSUserDefaults σε Swift

Ας δούμε ένα πρακτικό παράδειγμα: αποθήκευση και επαναφορά της κατάστασης ενσωμάτωσης (οθόνες υποδοχής) σε μια εφαρμογή iOS χρησιμοποιώντας NSUserDefaults. Κατά την πρώτη εκκίνηση, ο χρήστης βλέπει τις οθόνες ενσωμάτωσης, μετά την ολοκλήρωση των οποίων μια σημαία αποθηκεύεται στο UserDefaults. Στις επόμενες εκκινήσεις, η ενσωμάτωση παραλείπεται. Για SwiftUI χρησιμοποιείται @AppStorage, για UIKit — άμεση πρόσβαση στο UserDefaults.standard.

Αποθήκευση κατάστασης ενσωμάτωσης

Ας δημιουργήσουμε έναν διαχειριστή OnboardingManager που ενσωματώνει την εργασία με το UserDefaults για την αποθήκευση της κατάστασης ενσωμάτωσης. Ο διαχειριστής παρέχει την ιδιότητα isOnboardingCompleted για έλεγχο κατάστασης και τη μέθοδο markOnboardingCompleted για ορισμό της σημαίας. Το κλειδί αποθήκευσης έχει τοποθετηθεί σε σταθερά για την αποφυγή τυπογραφικών λαθών. Για δοκιμές μονάδας, ο διαχειριστής χρησιμοποιεί το πρωτόκολλο UserDefaultsProtocol, που επιτρέπει την αντικατάσταση του πραγματικού χώρου αποθήκευσης με 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)
    }
}

// Χρήση στην εφαρμογή
let onboardingManager = OnboardingManager()
if !onboardingManager.isOnboardingCompleted {
    showOnboarding()
} else {
    showMainScreen()
}

Για την αποθήκευση πιο σύνθετων ρυθμίσεων, όπως ένα δομημένο αντικείμενο Profile, συνιστάται η χρήση του πρωτοκόλλου Codable και JSONEncoder/JSONDecoder. Το αντικείμενο σειριοποιείται σε Data μέσω JSONEncoder, αποθηκεύεται μέσω set(_:forKey:), και κατά την ανάγνωση αποσειριοποιείται από Data πίσω σε αντικείμενο μέσω JSONDecoder. Αυτή η προσέγγιση επιτρέπει την αποθήκευση σύνθετων δομών στο UserDefaults χωρίς απώλεια ασφάλειας τύπων.

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

// Χρήση
let profile = UserProfile(name: "Άννα", age: 28, preferences: ["theme": "dark"])
UserDefaults.standard.save(profile, forKey: "user_profile")
let loaded = UserDefaults.standard.load(UserProfile.self, forKey: "user_profile")

Είναι σημαντικό να θυμόμαστε ότι το NSUserDefaults δεν προορίζεται για αποθήκευση μεγάλων όγκων δεδομένων. Η Apple συνιστά τον περιορισμό του μεγέθους των αποθηκευμένων δεδομένων σε μερικές δεκάδες kilobytes. Για την αποθήκευση μεγάλων αντικειμένων (εικόνες, έγγραφα, σειριοποιημένα μοντέλα) πρέπει να χρησιμοποιείται το FileManager με τον κατάλογο Documents ή το CoreData. Επιπλέον, το UserDefaults δεν υποστηρίζει εκδοσιοποίηση σχήματος δεδομένων — όταν αλλάζει η δομή του μοντέλου Codable, τα παλιά δεδομένα μπορεί να μην αποσειριοποιούνται και αυτό πρέπει να αντιμετωπιστεί στον κώδικα της εφαρμογής.

Συχνές Ερωτήσεις

Σε τι διαφέρει το NSUserDefaults από το SharedPreferences στο Android;

Και τα δύο είναι χώροι αποθήκευσης κλειδιού-τιμής, αλλά το NSUserDefaults υποστηρίζει περισσότερους τύπους (Data, Date, Array, Dictionary) και συγχρονίζεται αυτόματα με το iCloud. Το SharedPreferences αποθηκεύει δεδομένα σε XML, το NSUserDefaults — σε μορφή plist. Το NSUserDefaults έχει σύστημα τομέων με αναζήτηση σε αλληλουχία, το SharedPreferences χρησιμοποιεί απλή επίπεδη δομή με ονόματα αρχείων.

Είναι ασφαλής η αποθήκευση κωδικών πρόσβασης στο NSUserDefaults;

Όχι, το NSUserDefaults αποθηκεύει δεδομένα σε ανοιχτή μορφή χωρίς κρυπτογράφηση. Για κωδικούς πρόσβασης, διακριτικά και κλειδιά κρυπτογράφησης χρησιμοποιήστε το Keychain, το οποίο κρυπτογραφεί δεδομένα σε επίπεδο Secure Enclave. Το Keychain υποστηρίζει επίσης χαρακτηριστικά πρόσβασης όπως βιομετρική αυθεντικοποίηση (Face ID / Touch ID) πριν από την ανάγνωση του μυστικού.

Πώς συγχρονίζεται το NSUserDefaults μεταξύ συσκευών;

Για συγχρονισμό μεταξύ συσκευών του ίδιου χρήστη, χρησιμοποιήστε το NSUbiquitousKeyValueStore — τον χώρο αποθήκευσης κλειδιού-τιμής cloud iCloud. Τα δεδομένα που γράφονται σε αυτήν την υπηρεσία σε μια συσκευή εμφανίζονται αυτόματα σε όλες τις άλλες συσκευές του ίδιου λογαριασμού iCloud. Μέγιστος όγκος — 1 MB ανά εφαρμογή, 1024 κλειδιά.

Πώς διαγράφονται όλα τα δεδομένα από το NSUserDefaults;

Για διαγραφή όλων των δεδομένων, καλέστε τη μέθοδο removePersistentDomain(forName:) με το Bundle Identifier της εφαρμογής. Για διαγραφή μεμονωμένων τιμών χρησιμοποιήστε τη removeObject(forKey:). Για πλήρη επαναφορά των ρυθμίσεων εφαρμογής: UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!). Όλες οι διαγραφές εφαρμόζονται άμεσα στην προσωρινή μνήμη.

Ποιο είναι το μέγιστο μέγεθος δεδομένων στο NSUserDefaults;

Η Apple δεν θέτει αυστηρό όριο για το μέγεθος του NSUserDefaults, αλλά συνιστάται να μην υπερβαίνετε τα 100 KB για τον συνολικό όγκο όλων των αποθηκευμένων δεδομένων. Για μεγάλους όγκους χρησιμοποιήστε CoreData ή FileManager. Κατά την αποθήκευση άνω του 1 MB δεδομένων, η απόδοση ανάγνωσης κατά την εκκίνηση της εφαρμογής μπορεί να μειωθεί αισθητά.

Περίληψη

  • NSUserDefaults — ενσωματωμένος χώρος αποθήκευσης κλειδιού-τιμής Apple για απλές ρυθμίσεις εφαρμογής σε μορφή plist.
  • Υποστηρίζει εννέα τύπους δεδομένων: String, Int, Bool, Float, Double, Data, Date, Array και Dictionary.
  • Χρησιμοποιεί σύστημα τομέων με αναζήτηση σε αλληλουχία μέσω NSRegistrationDomain, NSGlobalDomain και του τομέα εφαρμογής.
  • Για συγχρονισμό μεταξύ συσκευών, η Apple παρέχει το NSUbiquitousKeyValueStore με όριο 1 MB ανά εφαρμογή.
  • Για ασφάλεια, χρησιμοποιήστε το Keychain για κωδικούς πρόσβασης και διακριτικά, όχι το NSUserDefaults.
  • Στο SwiftUI, ο προτιμώμενος τρόπος εργασίας είναι το Property Wrapper @AppStorage με αυτόματο συγχρονισμό UI.
  • Για μεγάλα ή δομημένα δεδομένα, επιλέξτε CoreData ή FileManager αντί για NSUserDefaults.

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης