NSUserDefaults — iOS, watchOS, tvOS va macOS-da ilova sozlamalari va konfiguratsiyalarini saqlash uchun mo'ljallangan kalit-qiymat ma'lumot omboridir. Ma'lumotlar ilova sandboxidagi plist faylida saqlanadi va NSUbiquitousKeyValueStore orqali avtomatik ravishda iCloud bilan sinxronlanadi. Rasmiy hujjatlarga ko'ra Apple Developer, 2025, NSUserDefaults primitiv turlarni saqlashni qo'llab-quvvatlaydi: String, Int, Bool, Float, Double, Data, Date, Array va Dictionary. Sinf Swift 3 dan boshlab UserDefaults deb nomlangan bo'lsa-da, uning Objective-C nomi NSUserDefaults kod bazasida va Apple hujjatlarida keng qo'llanilmoqda.
Asosiy fikrlar
NSUserDefaults (Swift-da UserDefaults) — Apple-ning kalit-qiymat juftliklarini plist formatida saqlash uchun o'rnatilgan mexanizmi. U barcha Apple platformalarida mavjud: iOS, iPadOS, watchOS, tvOS va macOS. Asosiy maqsad — foydalanuvchi afzalliklari, interfeys holati, birinchi ishga tushirish bayroqlari, tanlangan variantlar va ilova qayta ishga tushirilganda saqlanib qoladigan boshqa oddiy ma'lumotlarni saqlash.
Har bir iOS ilovasi izolyatsiyalangan sandboxga ega va NSUserDefaults ushbu sandbox ichidagi Library/Preferences katalogida Bundle Identifier nomli faylda saqlanadi. plist fayli kalit-qiymat juftliklarini o'z ichiga oladi, bu erda kalit satr, qiymat esa qo'llab-quvvatlanadigan turlardan biri. Fayl hajmi cheklanmagan, ammo Apple UserDefaults-da faqat sozlamalarni saqlashni tavsiya qiladi, katta hajmdagi ma'lumotlarni emas.
iOS 8 dan boshlab, NSUserDefaults App Groups-ni qo'llab-quvvatlaydi — bir dasturchining ilovalari va ularning kengaytmalari (vidjetlar, watchOS yordamchi ilovalari) o'rtasida umumiy ombor. Buning uchun App Group identifikatori bilan init?(suiteName:) initsializatoridan foydalaniladi. Bu, masalan, Today ekranidagi vidjetga asosiy ilovadan sozlamalarni o'qish imkonini beradi.
Jismoniy jihatdan, NSUserDefaults ikkilik plist faylida saqlanadi: {Sandbox}/Library/Preferences/com.example.myapp.plist. Fayl ixchamlik va o'qish tezligi uchun ikkilik plist formatidan (NSPropertyListBinaryFormat_v1_0) foydalanadi. macOS-da fayl moslik uchun XML formatida bo'lishi mumkin. Android-dagi SharedPreferences dan farqli o'laroq, UserDefaults plist fayllari Dictionary va Array orqali ichma-ich tuzilmalarni o'z ichiga olishi mumkin.
NSUserDefaults fayllari sukut bo'yicha shifrlanmaydi. Ma'lumotlar ochiq shaklda saqlanadi va qurilmaga jismoniy kirish yoki zaxira nusxa orqali o'qilishi mumkin. Maxfiy ma'lumotlarni (parollar, tokenlar, shifrlash kalitlari) saqlash uchun Apple operatsion tizim darajasida ma'lumotlarni avtomatik shifrlaydigan Keychain dan foydalanishni qat'iy tavsiya qiladi.
NSUserDefaults davriy disk sinxronizatsiyasi bilan xotirada keshlash printsipi asosida ishlaydi. Standart UserDefaults.standard nusxasiga birinchi murojaat qilinganda, tizim plist faylni Dictionary shaklida operativ xotiraga yuklaydi. Barcha keyingi o'qishlar xotiradan amalga oshiriladi. Yozish ham avval xotirada amalga oshiriladi va diskka sinxronizatsiya fonda davriy ravishda sodir bo'ladi.
Yozish operatsiyalari set(_:forKey:) metodidan foydalanadi, u ixtiyoriy Any? tipidagi qiymatni qabul qiladi. Qiymat nil bo'lishi mumkin — kalitni o'chirish uchun. Diskka darhol yozish uchun ilgari synchronize() metodidan foydalanilgan, ammo iOS 7 va OS X 10.9 dan boshlab endi talab qilinmaydi — tizim ma'lumotlarni muntazam ravishda avtomatik sinxronlaydi. Apple o'z hujjatlarida synchronize() ni ortiqcha deb rasman e'lon qilgan.
NSUserDefaults qiymatlarni qidirishni tashkil qilish uchun registr (domen) tizimidan foydalanadi. Ilova kalit bo'yicha qiymat so'raganda, UserDefaults domenlarni ma'lum tartibda ketma-ket tekshiradi: avval NSArgumentDomain (buyruq satri argumentlari), keyin ilova domeni (Application), so'ng NSGlobalDomain (tizim sozlamalari), keyin Til-spesifik domenlar va nihoyat NSRegistrationDomain (register(defaults:) orqali ro'yxatdan o'tgan sukutiy qiymatlar).
import Foundation
// Standart UserDefaults namunasi
let defaults = UserDefaults.standard
// Qiymatlarni yozish
defaults.set("Anna Petrova", forKey: "username")
defaults.set(28, forKey: "age")
defaults.set(true, forKey: "isLoggedIn")
// Sukutiy qiymatlarni ro'yxatdan o'tkazish
defaults.register(defaults: [
"theme": "system",
"fontSize": 14
])
// Sukutiy qiymatni qaytarish bilan o'qish
let theme = defaults.string(forKey: "theme") ?? "system"
let fontSize = defaults.integer(forKey: "fontSize")
NSRegistrationDomain — faqat operativ xotirada mavjud bo'lgan va diskka yozilmaydigan dasturiy domendir. U ilova o'z qiymatini ilova domeniga yozmaguncha faoliyat ko'rsatadigan sukutiy qiymatlarni o'rnatish uchun ishlatiladi. Bu rivojlanish bosqichida markazlashtirilgan holda o'zgartirilishi mumkin bo'lgan yagona sukutiy sozlamalar konfiguratsiya nuqtasini yaratishga imkon beradi.
NSUserDefaults ma'lumotlarni o'qish va yozish uchun tiplashtirilgan metodlar to'plamini taqdim etadi: string(forKey:), integer(forKey:), bool(forKey:), float(forKey:), double(forKey:), data(forKey:), array(forKey:), dictionary(forKey:) va object(forKey:). Har bir o'qish metodi saqlanadigan qiymat turini avtomatik aniqlaydigan mos set(_:forKey:) yozish metodiga ega. Swift versiyasi UserDefaults qattiq tiplanishdan foydalanadi, ammo Objective-C versiyasi id ni qabul qiladi va qaytaradi.
| O'qish metodi (Swift) | Ma'lumot turi | Sukutiy qiymat |
|---|---|---|
| string(forKey:) | String? | nil |
| integer(forKey:) | Int | 0 |
| bool(forKey:) | Bool | false |
| float(forKey:) | Float | 0.0 |
| double(forKey:) | Double | 0.0 |
| data(forKey:) | Data? | nil |
synchronize() metodi NSUserDefaults-da barcha o'zgarishlarni xotiradan diskka majburiy yozadi. iOS-ning dastlabki versiyalarida bu metodni har bir yozishdan keyin chaqirish kerak edi. iOS 7 dan boshlab tizim UserDefaults-ni fonda avtomatik sinxronlaydi va Apple synchronize() ni ortiqcha deb rasman e'lon qilgan. Ushbu metodni chaqirish xatoga olib kelmaydi, ammo qo'shimcha saqlash kafolatini bermaydi.
O'zgarishlarni kuzatish uchun NSUserDefaults UserDefaults.didChangeNotification bildirishnomasini va addObserver(_:forKeyPath:options:context:) KVO kuzatish metodini taqdim etadi. SwiftUI da UI yangilanishi bilan UserDefaults qiymatini avtomatik sinxronlaydigan @AppStorage Property Wrapper mavjud. @AppStorage UserDefaults bilan bir xil turlarni qo'llab-quvvatlaydi va SwiftUI ilovalarida sozlamalar bilan ishlashning afzal qilingan usulidir.
// KVO orqali o'zgarishlarni kuzatish
class SettingsViewModel: NSObject {
override func observeValue(
forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey: Any]?,
context: UnsafeMutableRawPointer?
) {
guard let keyPath else { return }
print("Kalit o'zgardi: \(keyPath)")
}
}
// SwiftUI - AppStorage
struct SettingsView: View {
@AppStorage("theme") private var theme: String = "system"
var body: some View {
Picker("Mavzu", selection: $theme) {
Text("Tizim").tag("system")
Text("Yorug'").tag("light")
Text("Qorong'i").tag("dark")
}
}
}
App Groups (ilova va kengaytmalar o'rtasida umumiy ombor) bilan ishlash uchun App Group identifikatori bilan UserDefaults(suiteName:) initsializatoridan foydalaniladi. Masalan, "group.com.example.myapp". Ushbu nusxaga yozilgan ma'lumotlar asosiy ilova, vidjet, watchOS yordamchi ilovasi va bir xil App Group ga tegishli boshqa kengaytmalardan foydalanish mumkin. Har bir suite nusxasi alohida plist faylida saqlanadi.
Qulayligi va soddaligiga qaramay, NSUserDefaults iOS-dagi barcha ma'lumot turlari uchun universal ombor emas. Hajm, kritiklik va xavfsizlik talablariga qarab, Apple har biri ma'lum foydalanish stsenariysi uchun optimallashtirilgan bir nechta alternativlarni taqdim etadi.
| Yechim | Qachon ishlatish kerak | Cheklovlar |
|---|---|---|
| NSUserDefaults | Interfeys sozlamalari va konfiguratsiya | Katta ma'lumotlar va sirlar uchun mos emas |
| Keychain | Parollar, tokenlar, shifrlash kalitlari | Foydalanish murakkabroq, sekinroq |
| CoreData | Bog'langan strukturali ma'lumotlar | 10-20 sozlama uchun ortiqcha |
| FileManager | Hujjatlar, rasmlar, ikkilik ma'lumotlar | Qo'lda fayl boshqaruvini talab qiladi |
| CloudKit | Qurilmalar o'rtasida bulutli sinxronizatsiya | iCloud hisobi va tarmoq ulanishini talab qiladi |
Keychain — Apple-ning maxfiy ma'lumotlar uchun himoyalangan ombori. NSUserDefaults dan farqli o'laroq, Keychain-dagi barcha ma'lumotlar mos qurilmalarda Secure Enclave apparat shifrlashidan foydalangan holda operatsion tizim darajasida shifrlanadi. Keychain qurilma bilan birga avtomatik bloklanadi va blokdan chiqariladi hamda Keychain Access Groups orqali bir dasturchining ilovalari o'rtasida kirish taqsimotini qo'llab-quvvatlaydi.
Keychain ning asosiy kamchiligi — API ning murakkabligi. Oddiy satrni saqlash uchun atributlarni ko'rsatgan holda SecItemAdd so'rovini yaratish kerak: sinf (kSecClassGenericPassword), xizmat (kSecAttrService), hisob (kSecAttrAccount) va ma'lumot (kSecValueData). Keychain bilan ishlashni soddalashtirish uchun UserDefaults ga o'xshash qulay kalit-qiymat interfeysini ta'minlaydigan KeychainAccess va SwiftKeychainWrapper kabi uchinchi tomon o'ramlari mavjud.
Amaliy misolni ko'rib chiqaylik: NSUserDefaults yordamida iOS ilovasida onboarding (tabrik ekranlari) holatini saqlash va tiklash. Birinchi ishga tushirishda foydalanuvchi onboarding ekranlarini ko'radi, ularni o'tgandan keyin bayroq UserDefaults da saqlanadi. Keyingi ishga tushirishlarda onboarding o'tkazib yuboriladi. SwiftUI uchun @AppStorage, UIKit uchun UserDefaults.standard ga to'g'ridan-to'g'ri kirish ishlatiladi.
Onboarding holatini saqlash uchun UserDefaults bilan ishlashni inkapsulyatsiya qiladigan OnboardingManager menejerini yaratamiz. Menejer holatni tekshirish uchun isOnboardingCompleted xususiyatini va bayroqni o'rnatish uchun markOnboardingCompleted metodini taqdim etadi. Saqlash kaliti xatolarning oldini olish uchun doimiyga chiqarilgan. Birlik testlari uchun menejer UserDefaultsProtocol protokolidan foydalanadi, bu haqiqiy omborni MockUserDefaults bilan almashtirishga imkon beradi.
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)
}
}
// Ilovada foydalanish
let onboardingManager = OnboardingManager()
if !onboardingManager.isOnboardingCompleted {
showOnboarding()
} else {
showMainScreen()
}
Strukturali Profile obyekti kabi murakkabroq sozlamalarni saqlash uchun Codable protokoli va JSONEncoder/JSONDecoder dan foydalanish tavsiya etiladi. Obyekt JSONEncoder orqali Data ga serializatsiya qilinadi, set(_:forKey:) orqali saqlanadi va o'qiyotganda JSONDecoder orqali Data dan qayta obyektga deserializatsiya qilinadi. Ushbu yondashuv tip xavfsizligini yo'qotmasdan UserDefaults da murakkab tuzilmalarni saqlashga imkon beradi.
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)
}
}
// Foydalanish
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")
Shuni yodda tutish kerakki, NSUserDefaults katta hajmdagi ma'lumotlarni saqlash uchun mo'ljallanmagan. Apple saqlanadigan ma'lumotlar hajmini bir necha o'n kilobayt bilan cheklashni tavsiya qiladi. Katta obyektlarni (rasmlar, hujjatlar, serializatsiya qilingan modellar) saqlash uchun Documents katalogi bilan FileManager yoki CoreData dan foydalanish kerak. Bundan tashqari, UserDefaults ma'lumot sxemasining versiyalashtirilishini qo'llab-quvvatlamaydi — Codable modelining tuzilishi o'zgarganda eski ma'lumotlar deserializatsiya qilinmasligi mumkin va buni ilova kodida boshqarish kerak.
Ko'p beriladigan savollar
Ikkalasi ham kalit-qiymat omborlari, ammo NSUserDefaults ko'proq turlarni (Data, Date, Array, Dictionary) qo'llab-quvvatlaydi va iCloud bilan avtomatik sinxronlanadi. SharedPreferences ma'lumotlarni XML da, NSUserDefaults plist formatida saqlaydi. NSUserDefaults kaskad qidiruvli domen tizimiga ega, SharedPreferences fayl nomlari bilan oddiy tekis strukturadan foydalanadi.
Yo'q, NSUserDefaults ma'lumotlarni shifrlamasdan ochiq shaklda saqlaydi. Parollar, tokenlar va shifrlash kalitlari uchun ma'lumotlarni Secure Enclave darajasida shifrlaydigan Keychain dan foydalaning. Keychain shuningdek sirni o'qishdan oldin biometrik autentifikatsiya (Face ID / Touch ID) kabi kirish atributlarini qo'llab-quvvatlaydi.
Bir foydalanuvchining qurilmalari o'rtasida sinxronizatsiya uchun NSUbiquitousKeyValueStore — iCloud bulutli kalit-qiymat omboridan foydalaning. Bir qurilmada ushbu xizmatga yozilgan ma'lumotlar avtomatik ravishda bir xil iCloud hisobining barcha boshqa qurilmalarida paydo bo'ladi. Maksimal hajm — ilova uchun 1 MB, 1024 kalit.
Barcha ma'lumotlarni o'chirish uchun ilovaning Bundle Identifier bilan removePersistentDomain(forName:) metodini chaqiring. Alohida qiymatlarni o'chirish uchun removeObject(forKey:) dan foydalaning. Ilova sozlamalarini to'liq tiklash uchun: UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!). Barcha o'chirishlar darhol xotira keshlarida qo'llaniladi.
Apple NSUserDefaults uchun qattiq chegara o'rnatmaydi, ammo barcha saqlangan ma'lumotlarning umumiy hajmi 100 KB dan oshmasligi tavsiya etiladi. Katta hajmlar uchun CoreData yoki FileManager dan foydalaning. 1 MB dan ortiq ma'lumot saqlaganda, ilovani ishga tushirishda o'qish unumdorligi sezilarli darajada pasayishi mumkin.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.