SwiftUI میں @AppStorage ایک property wrapper ہے جو UserDefaults کے ساتھ کام کرنے کے لیے ہے اور خود بخود قدر کو UI سے ہم آہنگ کرتا ہے۔ جب @AppStorage کے ذریعے اعلان کردہ کوئی خاصیت تبدیل ہوتی ہے، نئی قدر فوراً UserDefaults میں محفوظ ہو جاتی ہے، اور جب UserDefaults بیرونی طور پر — کسی ویجیٹ یا ایکسٹینشن کے ذریعے — تبدیل ہوتا ہے، View خود بخود دوبارہ کھینچ جاتا ہے۔ Apple Developer Documentation (2025) کے مطابق، @AppStorage String، Int، Double، Bool، Data، URL اور ان کے اختیاری ورژن کو سپورٹ کرتا ہے، جو دستی مشاہدے کے کوڈ کے بغیر صارف کی ترتیبات کا رد عمل ذخیرہ فراہم کرتا ہے۔
اہم نکات
@AppStorage ایک property wrapper ہے جسے Apple نے iOS 14 میں متعارف کرایا، جو View کی خاصیت کو UserDefaults میں ایک کلید سے جوڑتا ہے۔ خاصیت پڑھتے وقت، SwiftUI مخصوص کردہ کلید سے UserDefaults سے قدر لوڈ کرتا ہے۔ لکھتے وقت، نئی قدر محفوظ کرتا ہے اور View کو دوبارہ کھینچنے کی اطلاع دیتا ہے۔
@AppStorage سے پہلے، ڈویلپرز کو onAppear میں دستی طور پر UserDefaults پڑھنا، UserDefaults.didChangeNotification کو سبسکرائب کرنا، اور تبدیلیوں پر @State کو اپ ڈیٹ کرنا پڑتا تھا۔ @AppStorage پورے چکر کو خودکار بناتا ہے: ایک لائن کا اعلان 15-20 لائنوں کے بوائلر پلیٹ کوڈ کو بدل دیتا ہے۔ مزید برآں، @AppStorage دو طرفہ ہم آہنگی فراہم کرتا ہے — اگر UserDefaults کی قدر کسی دوسرے عمل (مثلاً App Extension یا Widget) سے تبدیل ہوتی ہے، تب بھی View اپ ڈیٹ حاصل کرے گا۔
فنی تعمیر کے لحاظ سے، @AppStorage کو DynamicProperty کے طور پر لاگو کیا گیا ہے، جو SwiftUI کو انحصار کو ٹریک کرنے اور مشاہدہ کردہ قدر کی تبدیلی پر View کو دوبارہ کھینچنے کی اجازت دیتا ہے۔ یہ اسے صارف کی ترتیبات: انٹرفیس کی زبان، فیچرز کو فعال/غیر فعال کرنا، آخری منتخب کردہ ٹیب، صارف نام محفوظ کرنے کے لیے مثالی بناتا ہے۔
اگرچہ @AppStorage اندرونی طور پر UserDefaults استعمال کرتا ہے، ذخیرہ کے ساتھ کام کرنے کے طریقے بنیادی طور پر مختلف ہیں۔ UserDefaults ایک نچلی سطح کا API ہے جس کے لیے پڑھنے، لکھنے اور تبدیلی کی اطلاعوں کا دستی انتظام درکار ہوتا ہے۔ @AppStorage ایک SwiftUI تجرید ہے جو فوری طور پر رد عمل کا رویہ فراہم کرتا ہے۔
UserDefaults ایک بار کے کاموں کے لیے موزوں ہے: ایپ شروع کرتے وقت ترتیبات لوڈ کرنا، تجزیات لکھنا، ٹوکنز کو کیش کرنا۔ @AppStorage ان ترتیبات کے لیے ہے جنہیں UI کو رد عمل سے اپ ڈیٹ کرنا چاہیے: تھیم سوئچ، زبان کا انتخاب، انٹرفیس کی حالت محفوظ کرنا۔ View کے اندر براہ راست UserDefaults استعمال کرنا ایک اینٹی پیٹرن ہے، کیونکہ اضافی سبسکرپشن کے بغیر View تبدیلیوں کے بارے میں نہیں جانتی۔
| پیرامیٹر | @AppStorage | UserDefaults |
|---|---|---|
| رد عمل | خودکار | اطلاعات کی سبسکرپشن درکار |
| بوائلر پلیٹ | 1 لائن فی خاصیت | 15-20 لائنیں فی خاصیت |
| اقسام | String، Int، Double، Bool، Data، URL | تمام اقسام + آرکائیو شدہ اشیاء |
| اپنی مرضی کی اقسام | RawRepresentable کے ذریعے | NSKeyedArchiver کے ذریعے |
| App Extension | خودکار ہم آہنگی | دستی سبسکرپشن |
رد عمل UI کے ساتھ سادہ ترتیبات کے لیے @AppStorage ترجیحی انتخاب ہے۔ پیچیدہ ڈیٹا (صفیں، لغات، اپنی مرضی کی اشیاء) کے لیے UserDefaults کو @State اور دستی تبدیلی سبسکرپشن کے ساتھ استعمال کریں، یا ساختی ذخیرہ کے لیے SwiftData / Core Data پر سوئچ کریں۔
@AppStorage معیاری اقسام کو سپورٹ کرتا ہے جنہیں UserDefaults براہ راست سیریلائز کر سکتا ہے: String، Int، Double، Bool، Data، URL۔ ہر قسم کے لیے ایک اختیاری ورژن (String?، Int?، Double?، Bool?، Data?، URL?) موجود ہے، جو "سیٹ نہیں" اور "خالی قدر" میں فرق کرنے کی اجازت دیتا ہے۔
RawRepresentable پروٹوکول کی تعمیل کرنے والی اپنی مرضی کی اقسام کو ذخیرہ کرنے کے لیے، @AppStorage خود بخود بھی کام کرتا ہے۔ اگر کسی enum کا rawValue String یا Int قسم کا ہے، تو اسے براہ راست استعمال کیا جا سکتا ہے: @AppStorage("theme") var theme: AppTheme = .system. SwiftUI خود بخود rawValue کے ذریعے قدر کو سیریلائز/ڈی سیریلائز کرتا ہے۔
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) بار لانچ کیا گیا")
}
}
}
مثال مختلف @AppStorage اقسام کا استعمال کرتی ہے: ڈیفالٹ قدر "Guest" کے ساتھ String، لانچ کاؤنٹر کے لیے Int، ڈارک تھیم کے لیے Bool، String قسم کے rawValue کے ساتھ AppTheme enum، اور آخری کھلنے کے وقت کے لیے اختیاری Date?۔ ہر خاصیت پہلی دلیل کے طور پر مخصوص کردہ UserDefaults کلید سے منسلک ہے۔ اگر پہلی لانچ پر کلید ذخیرہ میں موجود نہیں ہے تو ڈیفالٹ قدر استعمال ہوتی ہے۔
@AppStorage کے اہم فوائد میں سے ایک کسی بھی ذریعہ سے UserDefaults تبدیلیوں کا خودکار مشاہدہ ہے۔ اگر کوئی App Extension یا Widget قدر تبدیل کرتا ہے، تو پیرنٹ ایپ میں @AppStorage اطلاع حاصل کرتا ہے اور View کو دوبارہ کھینچتا ہے۔ یہ KVO (Key-Value Observing) میکانزم کے ذریعے حاصل کیا جاتا ہے جسے @AppStorage خود بخود UserDefaults.didChangeNotification پر ترتیب دیتا ہے۔
عملی طور پر، اس کا مطلب ہے کہ اگر صارف Widget میں کوئی ترتیب تبدیل کرتا ہے (مثلاً، ڈارک تھیم کو فعال کرتا ہے)، تو ایپ فوری طور پر تبدیلی کو پکڑ لیتی ہے۔ وہی ہم آہنگی مرکزی ایپ اور Share Extension، Watch App یا Today Widget کے درمیان کام کرتی ہے۔ ڈویلپر کو میان عمل ڈیٹا کے تبادلے کے لیے کوڈ لکھنے کی ضرورت نہیں ہے — @AppStorage یہ خود بخود کرتا ہے۔
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("ڈارک موڈ \(newValue) میں تبدیل ہو گیا")
}
}
}
}
Toggle @AppStorage کے ذریعے $isDarkMode سے منسلک ہے۔ ٹوگل کرنے پر، قدر خود بخود "isDarkMode" کلید کے تحت UserDefaults میں محفوظ ہو جاتی ہے۔ .onChange موڈیفائر تبدیلی پر ضمنی اثر انجام دینے کی اجازت دیتا ہے — مثلاً، تجزیات بھیجنا یا دوسری اسکرینوں کا UI اپ ڈیٹ کرنا۔ اگر Widget اسی کلید کو تبدیل کرتا ہے، تو @AppStorage بھی onChange کو متحرک کرے گا، جو حالت کی مستقل مزاجی کو یقینی بناتا ہے۔
آئیے ایک مکمل ایپ ترتیبات کی اسکرین دیکھتے ہیں جو تمام کنفیگریشنز کو ذخیرہ کرنے کے لیے @AppStorage استعمال کرتی ہے۔ فارم میں مختلف اقسام کی ترتیبات کے ساتھ حصے ہیں: ٹیکسٹ فیلڈز، ٹوگلز، کاؤنٹرز — تمام قدریں خود بخود UserDefaults میں محفوظ ہو جاتی ہیں۔
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("پروفائل")) {
TextField("Display name", text: $displayName)
}
Section(header: Text("ترجیحات")) {
Toggle("Enable notifications",
isOn: $notificationsEnabled)
Stepper("Max results: \(maxResults)",
value: $maxResults,
in: 10...100,
step: 5)
}
Section {
Button("ترتیبات دوبارہ مرتب کریں") {
UserDefaults.standard.removePersistentDomain(
forName: Bundle.main.bundleIdentifier!)
}
.tint(.red)
}
}
.navigationTitle("Settings")
}
}
}
فارم میں مختلف اقسام کی چار @AppStorage خصوصیات ہیں: نام کے لیے String، اطلاعوں کے لیے Bool، نتائج کی تعداد کے لیے Int اور منتخب ٹیب کے لیے String۔ تمام کنٹرول Binding ($displayName، $notificationsEnabled، وغیرہ) کے ذریعے خصوصیات سے منسلک ہیں۔ "Reset settings" بٹن ایپ ڈومین کو ہٹا کر تمام UserDefaults کو صاف کرتا ہے — اس کے بعد @AppStorage خود بخود ڈیفالٹ اقدار پر واپس آ جاتا ہے۔
struct SharedSettingsView: View {
let sharedDefaults = UserDefaults(suiteName: "group.com.example.app")
@AppStorage("widgetTheme", store: UserDefaults(suiteName: "group.com.example.app")!)
var widgetTheme: String = "سسٹم"
@AppStorage("widgetColor", store: UserDefaults(suiteName: "group.com.example.app")!)
var widgetColor: String = "نیلا"
var body: some View {
Form {
Picker("Widget theme", selection: $widgetTheme) {
Text("سسٹم").tag("system")
Text("لائٹ").tag("لائٹ")
Text("ڈارک").tag("ڈارک")
}
Picker("Accent color", selection: $widgetColor) {
Text("نیلا").tag("blue")
Text("سبز").tag("سبز")
Text("سرخ").tag("سرخ")
}
}
}
}
App Group (ایپ اور ایکسٹینشنز کے درمیان مشترکہ ذخیرہ) کے لیے @AppStorage store پیرامیٹر قبول کرتا ہے: UserDefaults(suiteName:)۔ قدریں مشترکہ کنٹینر میں محفوظ ہوتی ہیں جو مرکزی ایپ، Widget، Watch App اور اسی گروپ کی دیگر ایکسٹینشنز کے لیے دستیاب ہوتی ہیں۔ Widget ان ترتیبات کو پڑھ سکتا ہے، اور جب وہ ایپ میں تبدیل ہوتی ہیں، UserDefaults مشاہدہ میکانزم کے ذریعے Widget خود بخود اپ ڈیٹ ہو جاتا ہے۔
اکثر پوچھے گئے سوالات
@State قدر صرف میموری میں محفوظ کرتا ہے اور ایپ کے دوبارہ شروع ہونے پر ری سیٹ ہو جاتا ہے۔ @AppStorage قدر کو UserDefaults میں محفوظ کرتا ہے اور اگلی لانچ پر بحال کرتا ہے۔ عارضی اسکرین ڈیٹا کے لیے @State استعمال کریں، ترتیبات کے لیے @AppStorage جو دوبارہ شروع ہونے کے بعد بھی برقرار رہنی چاہئیں۔
ہاں، اگر Enum String یا Int قسم کے rawValue کے ساتھ RawRepresentable پروٹوکول کو لاگو کرتا ہے۔ مثال: @AppStorage("theme") var theme: AppTheme = .system. SwiftUI خود بخود rawValue کے ذریعے enum کو سیریلائز کرتا ہے اور لوڈ کرنے پر بحال کرتا ہے۔
معیاری ذخیرہ کے لیے UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!) یا مخصوص کلید کے لیے removeObject(forKey:) کال کریں۔ صاف کرنے کے بعد، تمام @AppStorage خصوصیات اعلان میں مخصوص کردہ ڈیفالٹ اقدار پر واپس آ جائیں گی۔
ہاں، ایپ اور ایکسٹینشنز کے درمیان ہم آہنگی کے لیے App Group استعمال کریں: @AppStorage("key", store: UserDefaults(suiteName: "group.com.example.app")!)۔ Widget، Share Extension اور Watch App ایک ہی UserDefaults کو پڑھ اور لکھ سکتے ہیں، اور تبدیلیاں خود بخود ٹریک ہوتی ہیں۔
@AppStorage UserDefaults استعمال کرتا ہے، جو چھوٹی مقدار کے ڈیٹا: ترتیبات، ٹوکنز، کاؤنٹرز کے لیے ڈیزائن کیا گیا ہے۔ تجویز کردہ حد فی ایپ 100 KB تک ہے۔ ساختی یا بڑے ڈیٹا (آبجیکٹ صفیں، میڈیا فائلیں) کے لیے SwiftData، Core Data یا فائل سسٹم استعمال کریں۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں