@AppStorage di SwiftUI — apa itu, UserDefaults dan penyimpanan pengaturan

Penulis: IT Sectr Diterbitkan: 2026-06-25 Waktu membaca: 7 mnt

@AppStorage di SwiftUI — property wrapper untuk bekerja dengan UserDefaults, yang secara otomatis menyinkronkan nilai dengan UI. Saat properti yang dideklarasikan melalui @AppStorage berubah, nilai baru segera disimpan di UserDefaults, dan ketika UserDefaults berubah dari luar — oleh widget atau ekstensi — View secara otomatis digambar ulang. Menurut Apple Developer Documentation (2025), @AppStorage mendukung String, Int, Double, Bool, Data, URL dan versi opsionalnya, menyediakan penyimpanan reaktif pengaturan pengguna tanpa kode observasi manual.

Poin Utama

  • @AppStorage — property wrapper untuk kerja reaktif dengan UserDefaults di SwiftUI
  • Simpan otomatis — nilai ditulis ke UserDefaults setiap kali berubah
  • Pembaruan UI otomatis — View digambar ulang saat UserDefaults berubah dari sumber mana pun
  • Tipe yang didukung: String, Int, Double, Bool, Data, URL dan versi opsional
  • Nilai default ditetapkan dalam deklarasi dan digunakan saat pertama kali dijalankan

Apa itu @AppStorage di SwiftUI?

@AppStorage adalah property wrapper yang diperkenalkan oleh Apple di iOS 14, yang menghubungkan properti View dengan kunci di UserDefaults. Saat membaca properti, SwiftUI memuat nilai dari UserDefaults berdasarkan kunci yang ditentukan. Saat menulis — menyimpan nilai baru dan memberi tahu View untuk menggambar ulang.

Sebelum munculnya @AppStorage, pengembang harus membaca UserDefaults secara manual di onAppear, berlangganan pemberitahuan UserDefaults.didChangeNotification dan memperbarui @State saat ada perubahan. @AppStorage mengotomatiskan seluruh siklus: deklarasi satu baris menggantikan 15–20 baris kode boilerplate. Lebih dari itu, @AppStorage menyediakan sinkronisasi dua arah — jika nilai UserDefaults diubah dari proses lain (misalnya, App Extension atau Widget), View tetap akan menerima pembaruan.

Secara arsitektur, @AppStorage diimplementasikan sebagai DynamicProperty, yang memungkinkan SwiftUI melacak dependensi dan menggambar ulang View saat nilai yang diamati berubah. Ini membuatnya ideal untuk menyimpan pengaturan pengguna: bahasa antarmuka, mengaktifkan/menonaktifkan fitur, tab terakhir yang dipilih, nama pengguna.

@AppStorage vs UserDefaults: perbandingan

Meskipun @AppStorage menggunakan UserDefaults di bawah kap, pendekatan kerja dengan penyimpanan berbeda secara fundamental. UserDefaults adalah API tingkat rendah yang memerlukan pengelolaan manual pembacaan, penulisan, dan pemberitahuan perubahan. @AppStorage adalah abstraksi SwiftUI yang memberikan perilaku reaktif langsung dari kotak.

UserDefaults cocok untuk operasi sekali pakai: memuat pengaturan saat startup aplikasi, menulis analitik, menyimpan cache token. @AppStorage — untuk pengaturan yang harus memperbarui UI secara reaktif: sakelar tema, pemilihan bahasa, menyimpan status antarmuka. Penggunaan langsung UserDefaults di dalam View adalah antipattern, karena View tidak mengetahui perubahan tanpa langganan tambahan.

Parameter@AppStorageUserDefaults
ReaktivitasOtomatisMemerlukan langganan pemberitahuan
Boilerplate1 baris per properti15–20 baris per properti
TipeString, Int, Double, Bool, Data, URLSemua tipe + objek arsip
Tipe kustomMelalui RawRepresentableMelalui NSKeyedArchiver
App ExtensionSinkronisasi otomatisLangganan manual

Untuk pengaturan sederhana dengan UI reaktif, @AppStorage adalah pilihan yang lebih disukai. Untuk data kompleks (array, kamus, objek kustom) gunakan kombinasi UserDefaults dengan @State dan langganan manual perubahan, atau beralih ke SwiftData / Core Data untuk penyimpanan terstruktur.

Tipe data yang didukung

@AppStorage mendukung tipe standar yang dapat diserialisasi langsung oleh UserDefaults: String, Int, Double, Bool, Data, URL. Untuk setiap tipe terdapat versi opsional (String?, Int?, Double?, Bool?, Data?, URL?), yang memungkinkan pembedaan antara “belum diatur” dan “nilai kosong”.

Untuk penyimpanan tipe kustom yang sesuai dengan protokol RawRepresentable, @AppStorage juga bekerja secara otomatis. Jika enum memiliki rawValue bertipe String atau Int, dapat digunakan langsung: @AppStorage("theme") var theme: AppTheme = .system. SwiftUI secara otomatis men-serialisasi/deserialisasi nilai melalui rawValue.

swift
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("Dijalankan \(launchCount) kali")
        }
    }
}

Dalam contoh digunakan berbagai tipe @AppStorage: String dengan nilai default “Guest”, Int untuk penghitung startup, Bool untuk tema gelap, enum AppTheme dengan rawValue bertipe String dan Date? opsional untuk waktu terakhir dibuka. Setiap properti terikat pada kunci UserDefaults yang ditentukan sebagai argumen pertama. Nilai default digunakan jika kunci tidak ada di penyimpanan saat pertama kali dijalankan.

Observasi perubahan Store

Salah satu keunggulan utama @AppStorage — pengamatan otomatis perubahan UserDefaults dari sumber mana pun. Jika App Extension atau Widget mengubah nilai, @AppStorage di aplikasi induk menerima pemberitahuan dan menggambar ulang View. Ini dicapai melalui mekanisme KVO (Key-Value Observing), yang secara otomatis diatur @AppStorage pada UserDefaults.didChangeNotification.

Dalam praktiknya, ini berarti jika pengguna mengubah pengaturan di Widget (misalnya, mengaktifkan tema gelap), aplikasi segera menangkap perubahan tersebut. Demikian pula sinkronisasi bekerja antara aplikasi utama dan Share Extension, Watch App atau Today Widget. Pengembang tidak perlu menulis kode untuk pertukaran data antar-proses — @AppStorage melakukannya secara otomatis.

swift
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("Mode gelap diubah menjadi \(newValue)")
                }
        }
    }
}

Toggle terhubung dengan $isDarkMode melalui @AppStorage. Saat diubah, nilai secara otomatis disimpan di UserDefaults di bawah kunci “isDarkMode”. Pengubah .onChange memungkinkan melakukan tindakan sampingan saat perubahan — misalnya, mengirim analitik atau memperbarui UI layar lain. Jika Widget mengubah kunci yang sama, @AppStorage juga akan memanggil onChange, memastikan konsistensi status.

Contoh kode @AppStorage

Mari kita lihat layar pengaturan aplikasi lengkap yang menggunakan @AppStorage untuk menyimpan semua konfigurasi. Formulir berisi bagian dengan berbagai jenis pengaturan: bidang teks, sakelar, penghitung — semua nilai secara otomatis disimpan di UserDefaults.

swift
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("Preferensi")) {
                    Toggle("Enable notifications",
                           isOn: $notificationsEnabled)
                    Stepper("Max results: \(maxResults)",
                           value: $maxResults,
                           in: 10...100,
                           step: 5)
                }

                Section {
                    Button("Reset pengaturan") {
                        UserDefaults.standard.removePersistentDomain(
                            forName: Bundle.main.bundleIdentifier!)
                    }
                    .tint(.red)
                }
            }
            .navigationTitle("Settings")
        }
    }
}

Formulir berisi empat properti @AppStorage dari berbagai tipe: String untuk nama, Bool untuk pemberitahuan, Int untuk jumlah hasil dan String untuk tab yang dipilih. Semua kontrol terhubung ke properti melalui Binding ($displayName, $notificationsEnabled dll.). Tombol “Reset settings” mereset semua UserDefaults, menghapus domain aplikasi — setelah itu @AppStorage secara otomatis kembali ke nilai default.

Sinkronisasi @AppStorage dengan App Group

swift
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 = "biru"

    var body: some View {
        Form {
            Picker("Widget theme", selection: $widgetTheme) {
                Text("Sistem").tag("system")
                Text("Terang").tag("terang")
                Text("Gelap").tag("gelap")
            }
            Picker("Accent color", selection: $widgetColor) {
                Text("Biru").tag("blue")
                Text("Hijau").tag("hijau")
                Text("Merah").tag("merah")
            }
        }
    }
}

Untuk App Group (penyimpanan bersama antara aplikasi dan ekstensi) @AppStorage menerima parameter store: UserDefaults(suiteName:). Nilai disimpan dalam wadah bersama yang dapat diakses oleh aplikasi utama, Widget, Watch App dan ekstensi lain dari grup yang sama. Widget dapat membaca pengaturan ini, dan saat perubahan di aplikasi, Widget secara otomatis diperbarui melalui mekanisme observasi UserDefaults.

Pertanyaan yang Sering Diajukan

Apa perbedaan antara @AppStorage dan @State?

@State menyimpan nilai hanya di memori dan direset saat aplikasi dijalankan ulang. @AppStorage menyimpan nilai di UserDefaults dan mengembalikannya saat startup berikutnya. Gunakan @State untuk data sementara layar, @AppStorage — untuk pengaturan yang harus bertahan saat restart.

Bisakah @AppStorage digunakan dengan Enum?

Ya, jika Enum mengimplementasikan protokol RawRepresentable dengan rawValue bertipe String atau Int. Contoh: @AppStorage("theme") var theme: AppTheme = .system. SwiftUI secara otomatis men-serialisasi enum melalui rawValue dan mengembalikannya saat dimuat.

Bagaimana cara menghapus semua nilai @AppStorage?

Panggil UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!) untuk penyimpanan standar atau removeObject(forKey:) untuk kunci tertentu. Setelah penghapusan, semua properti @AppStorage akan kembali ke nilai default yang ditentukan dalam deklarasi.

Apakah @AppStorage bekerja dengan App Extensions?

Ya, untuk sinkronisasi antara aplikasi dan ekstensi gunakan App Group: @AppStorage("key", store: UserDefaults(suiteName: "group.com.example.app")!). Widget, Share Extension dan Watch App dapat membaca dan menulis di UserDefaults yang sama, dan perubahan dilacak secara otomatis.

Berapa banyak data yang dapat disimpan di @AppStorage?

@AppStorage menggunakan UserDefaults, yang dirancang untuk volume kecil data: pengaturan, token, penghitung. Batas yang disarankan — hingga 100 KB per aplikasi. Untuk data terstruktur atau besar (array objek, file media) gunakan SwiftData, Core Data atau sistem file.

Ringkasan

  • @AppStorage — property wrapper untuk penyimpanan reaktif pengaturan di UserDefaults
  • Simpan otomatis dan pembaruan UI otomatis saat nilai berubah dari sumber mana pun
  • Mendukung String, Int, Double, Bool, Data, URL dan RawRepresentable enums
  • Nilai default ditetapkan dalam deklarasi dan dikembalikan saat pertama kali dijalankan
  • App Group memungkinkan sinkronisasi @AppStorage antara aplikasi dan ekstensi
  • UserDefaults hanya cocok untuk volume kecil data — hingga 100 KB
  • Gunakan @AppStorage untuk pengaturan pengguna, @State — untuk status sementara layar

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga