@AppStorage SwiftUI-də — UserDefaults ilə iş üçün property wrapper, avtomatik olaraq dəyəri UI ilə sinxronlaşdırır. @AppStorage vasitəsilə elan edilmiş xassə dəyişdikdə, yeni dəyər dərhal UserDefaults-da saxlanılır və UserDefaults kənardan — vidjet və ya genişlənmə tərəfindən dəyişdirildikdə — View avtomatik olaraq yenidən çəkilir. Apple Developer Documentation (2025)-yə görə, @AppStorage String, Int, Double, Bool, Data, URL və onların optional versiyalarını dəstəkləyir, əl ilə müşahidə kodu olmadan reaktiv istifadəçi parametrlərinin saxlanmasını təmin edir.
Əsas məqamlar
@AppStorage — Apple tərəfindən iOS 14-də təqdim edilmiş, View xassəsini UserDefaults açarı ilə birləşdirən property wrapper-dır. Xassə oxunduqda SwiftUI göstərilən açar üzrə UserDefaults-dan dəyəri yükləyir. Yazarkən — yeni dəyəri saxlayır və View-ə yenidən çəkilmə zərurəti barədə xəbərdarlıq edir.
@AppStorage yaranmazdan əvvəl tərtibatçılar əl ilə UserDefaults-ı onAppear-da oxumalı, UserDefaults.didChangeNotification bildirişinə abunə olmalı və dəyişikliklər zamanı @State-i yeniləməli idilər. @AppStorage bütün dövrü avtomatlaşdırır: bir sətirdə elan 15–20 sətir boilerplate kodu əvəz edir. Üstəlik, @AppStorage ikitərəfli sinxronizasiya təmin edir — əgər UserDefaults dəyəri başqa prosesdən (məsələn, App Extension və ya Widget) dəyişdirilərsə, View yenə də yeniləmə alacaq.
Arxitektura baxımından @AppStorage DynamicProperty kimi tətbiq edilmişdir ki, bu da SwiftUI-ə asılılıqları izləməyə və müşahidə olunan dəyər dəyişdikdə View-i yenidən çəkməyə imkan verir. Bu onu istifadəçi parametrlərinin saxlanması üçün ideal edir: interfeys dili, funksiyaların açılması/söndürülməsi, son seçilmiş tab, istifadəçi adı.
@AppStorage UserDefaults-dan istifadə etsə də, yaddaşla işə yanaşmalar prinsipial olaraq fərqlənir. UserDefaults — aşağı səviyyəli API, oxuma, yazma və dəyişiklik bildirişlərinin əl ilə idarə edilməsini tələb edir. @AppStorage — qutudan çıxan kimi reaktiv davranış təmin edən SwiftUI abstraksiyasıdır.
UserDefaults birdəfəlik əməliyyatlar üçün uyğundur: tətbiq başlanğıcında parametrlərin yüklənməsi, analitikanın yazılması, tokenlərin keşlənməsi. @AppStorage — UI-i reaktiv yeniləməli parametrlər üçün: mövzu keçidləri, dil seçimi, interfeys vəziyyətinin saxlanması. UserDefaults-ı birbaşa View daxilində istifadə etmək anti-nümunədir, çünki View əlavə abunə olmadan dəyişikliklərdən xəbərdar olmur.
| Parametr | @AppStorage | UserDefaults |
|---|---|---|
| Reaktivlik | Avtomatik | Bildirişlərə abunə tələb edir |
| Boilerplate | Xassə başına 1 sətir | Xassə başına 15–20 sətir |
| Tiplər | String, Int, Double, Bool, Data, URL | Bütün tiplər + arxiv obyektləri |
| Xüsusi tiplər | RawRepresentable vasitəsilə | NSKeyedArchiver vasitəsilə |
| App Extension | Avtomatik sinxronizasiya | Əl ilə abunə |
Sadə parametrlər və reaktiv UI üçün @AppStorage üstünlük verilən seçimdir. Mürəkkəb məlumatlar (massivlər, lüğətlər, xüsusi obyektlər) üçün UserDefaults-ı @State və əl ilə dəyişiklik abunəsi ilə birlikdə istifadə edin və ya strukturlaşdırılmış saxlama üçün SwiftData / Core Data-ya keçin.
@AppStorage UserDefaults-ın birbaşa seriyalaşdıra bildiyi standart tipləri dəstəkləyir: String, Int, Double, Bool, Data, URL. Hər tip üçün optional versiya mövcuddur (String?, Int?, Double?, Bool?, Data?, URL?), “quraşdırılmayıb” və “boş dəyər” arasında fərqləndirməyə imkan verir.
RawRepresentable protokoluna uyğun xüsusi tiplərin saxlanması üçün @AppStorage avtomatik işləyir. Əgər enum rawValue tipi String və ya Int-dirsə, onu birbaşa istifadə etmək olar: @AppStorage("theme") var theme: AppTheme = .system. SwiftUI avtomatik olaraq dəyəri rawValue vasitəsilə seriyalaşdırır/deseriyalaşdırır.
enum AppTheme: String {
case system, light, dark
}
struct SettingsView: View {
@AppStorage("username") var username: String = "Guest"
@AppStorage("launchCount") var launchCount: Int = 0
@AppStorage("isDarkMode") var isDarkMode: Bool = false
@AppStorage("appTheme") var theme: AppTheme = .system
@AppStorage("lastOpened") var lastOpened: Date? = nil
var body: some View {
Form {
TextField("Username", text: $username)
Toggle("Dark mode", isOn: $isDarkMode)
Text("\(launchCount) dəfə işə salındı")
}
}
}
Nümunədə müxtəlif @AppStorage tipləri istifadə olunub: defolt dəyəri “Guest” olan String, işə salma sayğacı üçün Int, qaranlıq mövzu üçün Bool, rawValue tipi String olan enum AppTheme və son açılış vaxtı üçün optional Date?. Hər xassə ilk arqumentdə göstərilən UserDefaults açarına bağlıdır. Defolt dəyər ilk işə salınmada açarda dəyər yoxdursa istifadə olunur.
@AppStorage-in əsas üstünlüklərindən biri — UserDefaults dəyişikliklərinin istənilən mənbədən avtomatik müşahidəsidir. Əgər App Extension və ya Widget dəyəri dəyişərsə, ana tətbiqdə @AppStorage bildiriş alır və View-i yenidən çəkir. Buna @AppStorage-in UserDefaults.didChangeNotification üzərində avtomatik qurduğu KVO (Key-Value Observing) mexanizmi vasitəsilə nail olunur.
Praktikada bu o deməkdir ki, istifadəçi Widget-də parametri dəyişərsə (məsələn, qaranlıq mövzunu yandırsa), tətbiq dərhal bu dəyişikliyi qəbul edir. Eyni şəkildə əsas tətbiq, Share Extension, Watch App və Today Widget arasında sinxronizasiya işləyir. Tərtibatçı proseslərarası məlumat mübadiləsi üçün kod yazmalı deyil — @AppStorage bunu avtomatik edir.
struct ThemeSettingView: View {
@AppStorage("isDarkMode") var isDarkMode: Bool = false
var body: some View {
VStack {
Toggle("Dark Mode", isOn: $isDarkMode)
.onChange(of: isDarkMode) { oldValue, newValue in
print("Qaranlıq rejim dəyişdi: \(newValue)")
}
}
}
}
Toggle @AppStorage vasitəsilə $isDarkMode ilə bağlıdır. Keçid edildikdə dəyər avtomatik olaraq UserDefaults-da “isDarkMode” açarı altında saxlanılır. .onChange modifikatoru dəyişiklik zamanı əlavə tədbir görməyə imkan verir — məsələn, analitika göndərmək və ya digər ekranların UI-ni yeniləmək. Əgər Widget eyni açarı dəyişərsə, @AppStorage də onChange-i çağıracaq, vəziyyətin ardıcıllığını təmin edərək.
Bütün konfiqurasiyaları saxlamaq üçün @AppStorage istifadə edən tam tətbiq parametrləri ekranını nəzərdən keçirək. Forma müxtəlif parametr tipləri olan bölmələrdən ibarətdir: mətn sahələri, keçid açarı, sayğaclar — bütün dəyərlər avtomatik UserDefaults-da saxlanılır.
struct AppSettingsView: View {
@AppStorage("displayName") var displayName = ""
@AppStorage("notificationsEnabled") var notificationsEnabled = true
@AppStorage("maxResults") var maxResults = 25
@AppStorage("selectedTab") var selectedTab = "home"
var body: some View {
NavigationStack {
Form {
Section(header: Text("Profil")) {
TextField("Display name", text: $displayName)
}
Section(header: Text("Parametrlər")) {
Toggle("Enable notifications",
isOn: $notificationsEnabled)
Stepper("Max results: \(maxResults)",
value: $maxResults,
in: 10...100,
step: 5)
}
Section {
Button("Parametrləri sıfırla") {
UserDefaults.standard.removePersistentDomain(
forName: Bundle.main.bundleIdentifier!)
}
.tint(.red)
}
}
.navigationTitle("Settings")
}
}
}
Formada müxtəlif tipli dörd @AppStorage xassəsi var: ad üçün String, bildirişlər üçün Bool, nəticələrin sayı üçün Int və seçilmiş tab üçün String. Bütün idarəetmə elementləri Binding vasitəsilə xassələrə bağlıdır ($displayName, $notificationsEnabled və s.). “Reset settings” düyməsi bütün UserDefaults-ı sıfırlayır, tətbiq domenini silir — bundan sonra @AppStorage avtomatik olaraq defolt dəyərlərə qayıdır.
struct SharedSettingsView: View {
let sharedDefaults = UserDefaults(suiteName: "group.com.example.app")
@AppStorage("widgetTheme", store: UserDefaults(suiteName: "group.com.example.app")!)
var widgetTheme: String = "sistem"
@AppStorage("widgetColor", store: UserDefaults(suiteName: "group.com.example.app")!)
var widgetColor: String = "mavi"
var body: some View {
Form {
Picker("Widget theme", selection: $widgetTheme) {
Text("Sistem").tag("system")
Text("İşıqlı").tag("işıqlı")
Text("Qaranlıq").tag("qaranlıq")
}
Picker("Accent color", selection: $widgetColor) {
Text("Mavi").tag("blue")
Text("Yaşıl").tag("yaşıl")
Text("Qırmızı").tag("qırmızı")
}
}
}
}
App Group (tətbiq və genişlənmələr arasında ümumi yaddaş) üçün @AppStorage store parametrini qəbul edir: UserDefaults(suiteName:). Dəyərlər əsas tətbiq, Widget, Watch App və eyni qrupun digər genişlənmələri üçün əlçatan olan ümumi konteynerdə saxlanılır. Widget bu parametrləri oxuya bilər, tətbiqdə dəyişiklik zamanı isə UserDefaults müşahidə mexanizmi vasitəsilə Widget avtomatik yenilənir.
Tez-tez verilən suallar
@State dəyəri yalnız yaddaşda saxlayır və tətbiq yenidən başladıqda sıfırlanır. @AppStorage dəyəri UserDefaults-da saxlayır və növbəti başlanğıcda bərpa edir. @State-i ekranın müvəqqəti məlumatları üçün, @AppStorage-i isə yenidən başlanğıcı keçməli olan parametrlər üçün istifadə edin.
Bəli, əgər Enum rawValue tipi String və ya Int olan RawRepresentable protokolunu tətbiq edirsə. Nümunə: @AppStorage("theme") var theme: AppTheme = .system. SwiftUI avtomatik olaraq enum-u rawValue vasitəsilə seriyalaşdırır və yükləmədə bərpa edir.
Standart yaddaş üçün UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!) və ya konkret açar üçün removeObject(forKey:) çağırın. Təmizləmədən sonra bütün @AppStorage xassələri elanda göstərilən defolt dəyərlərə qayıdacaq.
Bəli, tətbiq və genişlənmələr arasında sinxronizasiya üçün App Group istifadə edin: @AppStorage("key", store: UserDefaults(suiteName: "group.com.example.app")!). Widget, Share Extension və Watch App eyni UserDefaults-da oxuya və yaza bilər, dəyişikliklər isə avtomatik izlənilir.
@AppStorage kiçik həcmli məlumatlar üçün nəzərdə tutulmuş UserDefaults-dan istifadə edir: parametrlər, tokenlər, sayğaclar. Tövsiyə olunan limit — tətbiq başına 100 KB-a qədər. Strukturlaşdırılmış və ya böyük məlumatlar (obyekt massivləri, media fayllar) üçün SwiftData, Core Data və ya fayl sistemindən istifadə edin.
Xülasə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun