SharedPreferences
Simpan data kecil persisten: tema, token, onboarding.
Kenapa SharedPreferences Ada: Masalah yang Diselesaikan
Hampir setiap aplikasi butuh menyimpan hal-hal kecil yang harus bertahan setelah aplikasi ditutup: pilihan dark mode, status onboarding ("sudah pernah dibuka?"), token login, atau bahasa yang dipilih. Membuat tabel database hanya untuk menyimpan satu boolean jelas berlebihan.
SharedPreferences menyelesaikan ini dengan penyimpanan key-value yang persisten dan super ringan: di Android ia memakai SharedPreferences XML, di iOS memakai NSUserDefaults. API-nya async tapi sederhana, dan baca tulisnya cukup cepat untuk data kecil.
Contoh Dasar
flutter pub add shared_preferencesfinal prefs = await SharedPreferences.getInstance();
// simpan:
await prefs.setBool('gelap', true);
await prefs.setString('token', 'abc123');
await prefs.setInt('buka_ke', 3);
// baca (dengan nilai default kalau key belum ada):
final gelap = prefs.getBool('gelap') ?? false;
final token = prefs.getString('token');Perhatikan pola ??: getString mengembalikan null kalau key belum pernah disimpan, jadi selalu sediakan fallback.
Contoh Nyata: Service yang Rapi
Memanggil SharedPreferences.getInstance() di setiap widget itu berantakan dan rawan lupa await. Bungkus dalam satu service:
class PengaturanService {
PengaturanService._();
static final PengaturanService instance = PengaturanService._();
static const _keyGelap = 'pengaturan_gelap';
static const _keyOnboarding = 'pengaturan_onboarding_selesai';
SharedPreferences? _prefs;
Future<void> init() async {
_prefs ??= await SharedPreferences.getInstance();
}
bool get modeGelap => _prefs?.getBool(_keyGelap) ?? false;
Future<void> setModeGelap(bool v) async {
await _prefs?.setBool(_keyGelap, v);
}
bool get onboardingSelesai =>
_prefs?.getBool(_keyOnboarding) ?? false;
Future<void> tandaiOnboardingSelesai() async {
await _prefs?.setBool(_keyOnboarding, true);
}
}
// di main:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await PengaturanService.instance.init();
runApp(const MyApp());
}Kunci disimpan sebagai konstanta privat supaya tidak ada typo key yang menyebabkan bug "data hilang" yang misterius.
Edge Case yang Perlu Diwaspadai
getInstance()itu async dan tidak murah. Panggil sekali di awal (seperti contoh di atas), jangan di setiapbuild.- Tipe data terbatas: hanya
int,double,bool,String, danList<String>. Butuh objek kompleks? Serialisasi ke JSON string dulu denganjsonEncode. - Tidak ada enkripsi. Token login di sini bisa dibaca siapa pun yang punya akses ke file aplikasi. Untuk data sensitif pakai
flutter_secure_storage. - Hati-hati dengan
clear(): ia menghapus SEMUA key, termasuk yang dipakai package lain. Lebih amanremove()key milikmu satu per satu. - Key collision: beri prefix yang jelas (
pengaturan_,cache_) supaya tidak tabrakan dengan key dari package lain. reload(): di platform tertentu, perubahan dari luar (jarang terjadi) butuhprefs.reload()agar terbaca. Untuk pemakaian normal tidak diperlukan.
Kapan JANGAN Pakai SharedPreferences
- Data besar atau banyak baris (daftar produk, riwayat transaksi): pakai
sqfliteatau database lokal lain. - Data sensitif (password, token refresh, PIN): pakai
flutter_secure_storageyang terenkripsi. - Data yang harus sinkron antar device: SharedPreferences murni lokal. Butuh backend atau sinkronisasi cloud.
- State sementara yang tidak perlu persisten (filter yang sedang dipilih, tab aktif): cukup state management biasa seperti Riverpod atau
setState.
Catatan teknis: Setelah
getInstance()pertama selesai, semua operasi baca (getBool,getString, dan kawan-kawan) sebenarnya sinkron dari cache di memori, jadi aman dipanggil di dalambuildtanpaawait. Yang tetap async hanya operasi tulis dan pemanggilangetInstance()pertama.
Tantangan
Ingat tema
Simpan pilihan dark mode ke SharedPreferences setiap toggle, dan muat saat app start agar pilihan tidak hilang.