Mobile Development • Flutter & Dart
💾STORAGE
📦DATA
🔑PREFS
{ }JSON
🐝HIVE
🗄️SQLITE

BAB 10

LOCAL STORAGE & DATA MANAGEMENT

Belajar menyimpan data di perangkat: SharedPreferences, JSON, Serialization, Hive, dan SQLite — sampai membangun Aplikasi Catatan Harian.

KELAS 10 • SEMESTER 1 23 SLIDE INTERAKTIF

Gunakan tombol ◀ ▶ atau panah keyboard untuk navigasi

02Orientasi

Tujuan Pembelajaran

Setelah mempelajari bab ini, kamu akan mampu:

🔑 Menyimpan

Menyimpan data sederhana dengan SharedPreferences agar tidak hilang saat aplikasi ditutup.

{ } Mengubah

Mengubah objek Dart menjadi JSON dan sebaliknya (serialization & deserialization).

🗄️ Mengelola

Mengenal database lokal Hive & SQLite serta kapan memakai masing-masing.

Local Storage SharedPrefs JSON Serialization Hive / SQLite Mini Project
03Jembatan dari BAB 9

Recap: Dari State Management ke Storage

Di BAB 9 kamu belajar State Management — mengelola data selama aplikasi berjalan. Tapi ada satu masalah…

BAB 9 — State Management

Data disimpan di memori (RAM). Bisa berubah secara reaktif lewat setStateProvider.

⚠️ Masalahnya

Begitu aplikasi ditutup atau HP restart, semua state hilang! Data di RAM bersifat sementara.

BAB 10 — Local Storage

Kita simpan data ke penyimpanan permanen (disk) agar tetap ada walau aplikasi ditutup. Inilah persistence.

💡 Analogi: State = catatan di papan tulis (terhapus saat kelas bubar). Local Storage = catatan di buku tulis (tetap ada besok).

04Konsep Dasar

Apa itu Local Storage?

Local Storage adalah penyimpanan data di dalam perangkat (HP) itu sendiri, tanpa perlu internet/server.

Bayangkan laci meja belajarmu. Kamu bisa menaruh (simpan) buku ke dalam laci, lalu mengambilnya lagi kapan pun. Laci tetap menyimpan isinya walau kamu pergi sekolah. Local Storage bekerja persis seperti laci itu untuk data aplikasi.

  • ✅ Data tetap ada walau aplikasi ditutup
  • ✅ Tidak butuh koneksi internet
  • ✅ Cepat diakses karena ada di perangkat
📕 nama
📗 skor
📘 setting
▶ DEMO INTERAKTIF

Klik untuk "membuka laci" — seperti membaca/menyimpan data ke storage.

05SharedPreferences

SharedPreferences — Konsep

SharedPreferences menyimpan data sederhana berupa pasangan key–value (kunci–nilai). Cocok untuk: nama user, skor, tema gelap/terang, status login.

Seperti catatan tempel (sticky note) di pintu kulkas. Setiap catatan punya label (key) dan isi (value). Mau tahu "belanja apa?" → cari note berlabel belanja. Praktis untuk info kecil, tapi tidak untuk data besar & rumit.

Tipe data yang didukung: StringintdoubleboolList<String>

nama:
"Sahil"
skor:
95
darkMode:
true
login:
false

Setiap note = satu key : value

06SharedPreferences

SharedPreferences — Code & Demo

shared_prefs.dart
import 'package:shared_preferences/shared_preferences.dart';

// MENYIMPAN data (set)
Future<void> simpanNama(String nama) async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString('nama', nama); // key : value
}

// MEMBACA data (get)
Future<String> bacaNama() async {
  final prefs = await SharedPreferences.getInstance();
  // jika belum ada, beri nilai default 'Tamu'
  return prefs.getString('nama') ?? 'Tamu';
}

// MENGHAPUS data
Future<void> hapusNama() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.remove('nama');
}
▶ DEMO: SIMULASI get / set (pakai localStorage browser)
// hasil muncul di sini...

💡 Di browser kita pakai localStorage sebagai analogi SharedPreferences di Flutter — konsepnya sama: key–value yang persisten.

07JSON

Apa itu JSON?

JSON (JavaScript Object Notation) adalah format teks untuk menyusun data secara terstruktur, agar mudah disimpan & dikirim.

JSON ibarat surat dalam amplop yang rapi. Isinya ditulis dengan format baku: ada nama bagian (key) dan isinya (value). Karena formatnya standar, siapa pun (atau aplikasi apa pun) bisa membaca isi surat itu tanpa bingung. Data dikemas jadi teks → mudah dikirim & disimpan.

  • 📮 Objek dibungkus kurung kurawal { }
  • 📋 Daftar dibungkus kurung siku [ ]
  • 🔖 Format: "key": value
{
 "judul":"Belajar",
 "selesai":true
}

Surat terstruktur yang bisa dibaca aplikasi mana pun

08JSON

JSON — Struktur & Syntax

catatan.json
{
  "id": 1,
  "judul": "Belajar Flutter",
  "isi": "Hari ini belajar JSON",
  "selesai": false,
  "tags": ["sekolah", "coding"],
  "penulis": {
    "nama": "Sahil",
    "kelas": "10 RPL"
  }
}
▶ DEMO: PARSE JSON
// klik untuk parse...

🔢 Number"id": 1 (tanpa tanda kutip)

🔤 String"judul": "Belajar" (pakai kutip ganda)

Boolean"selesai": false

📋 Array"tags": [...] (daftar nilai)

📦 Object"penulis": {...} (objek bersarang)

09Serialization

Serialization (Object ➜ JSON)

Serialization = mengubah objek Dart menjadi teks JSON, supaya bisa disimpan atau dikirim.

Dart Object Catatan(...) toJson() / jsonEncode() JSON String '{"judul":...}'
model.dart
class Catatan {
  final String judul;
  final bool selesai;
  Catatan(this.judul, this.selesai);

  // Object  ➜  Map  ➜  JSON String
  Map<String, dynamic> toJson() => {
    'judul': judul,
    'selesai': selesai,
  };
}

📌 Mengapa perlu? Storage (file/SharedPrefs) hanya bisa menyimpan teks, bukan objek Dart langsung. Maka objek "diterjemahkan" dulu jadi teks JSON.

🔁 Alur: Object Dart → toJson() jadi Map → jsonEncode() jadi String.

10Deserialization

Deserialization (JSON ➜ Object)

Deserialization = kebalikannya. Mengubah teks JSON kembali menjadi objek Dart agar bisa dipakai program.

Dart Object Catatan(...) fromJson() / jsonDecode() JSON String '{"judul":...}'
model.dart
class Catatan {
  final String judul;
  final bool selesai;
  Catatan(this.judul, this.selesai);

  // JSON Map  ➜  Object Dart (named constructor)
  factory Catatan.fromJson(Map<String, dynamic> json) {
    return Catatan(
      json['judul'] as String,
      json['selesai'] as bool,
    );
  }
}

📌 Kapan dipakai? Saat membaca data dari storage: teks JSON dibaca → diubah jadi objek → ditampilkan di UI.

🔁 Alur: String → jsonDecode() jadi Map → fromJson() jadi Object Dart.

11Praktik

Serialize + Deserialize — Demo Dart

main.dart
import 'dart:convert';

void main() {
  // 1. Buat objek
  final c = Catatan('Belajar JSON', false);

  // 2. SERIALIZE: Object ➜ JSON String
  String jsonStr = jsonEncode(c.toJson());
  print(jsonStr); // {"judul":"Belajar JSON","selesai":false}

  // 3. DESERIALIZE: JSON String ➜ Object
  Map<String, dynamic> map = jsonDecode(jsonStr);
  Catatan c2 = Catatan.fromJson(map);
  print(c2.judul); // Belajar JSON
}
▶ DEMO: ENCODE & DECODE LANGSUNG
JSON String:
// ...
Hasil Object:
// ...
12Hive

Hive — Pengantar

Hive adalah database lokal NoSQL yang sangat cepat & ringan untuk Flutter. Data disimpan dalam Box (mirip kotak/wadah).

Bayangkan sarang lebah (hive). Setiap sel heksagonal menyimpan madu di tempatnya masing-masing, rapi dan cepat diambil. Hive bekerja begitu: tiap data ditaruh di "sel" dengan kunci, dan bisa diambil super cepat tanpa query rumit.

  • ⚡ Sangat cepat (lebih dari SharedPreferences untuk banyak data)
  • 📦 Cocok untuk objek/list yang lebih kompleks
  • 🚫 Tanpa SQL — cukup put / get dengan key
box
key1
key2
data
data
🍯

Tiap sel = satu data dalam Box

13Hive

Hive — Setup & Basic Usage

hive_setup.dart
import 'package:hive_flutter/hive_flutter.dart';

void main() async {
  // 1. Inisialisasi Hive
  await Hive.initFlutter();

  // 2. Buka sebuah Box (wadah penyimpanan)
  var box = await Hive.openBox('catatanBox');

  runApp(MyApp());
}
hive_crud.dart
var box = Hive.box('catatanBox');

// CREATE / UPDATE — simpan data
box.put('judul', 'Belajar Hive');
box.put('selesai', false);

// READ — ambil data
String judul = box.get('judul');       // 'Belajar Hive'
var x = box.get('kosong', defaultValue: '-');

// DELETE — hapus data
box.delete('judul');

// Ambil semua nilai
print(box.values.toList());

💡 box.put(key, value) = menaruh madu ke sel. box.get(key) = mengambilnya kembali.

14SQLite

SQLite — Pengantar

SQLite adalah database relasional (berbasis tabel) yang tertanam di perangkat. Di Flutter dipakai lewat package sqflite. Datanya tersusun dalam tabel berisi baris & kolom, dan diakses dengan bahasa SQL.

Seperti lemari arsip kantor yang sangat terorganisir. Tiap laci punya label, tiap folder punya baris data dengan kolom rapi (nama, tanggal, isi). Saat butuh data tertentu, kamu bisa "memerintah" lemari: "ambil semua arsip yang selesai = true" — itulah SQL query.

Cocok untuk: data banyak & berelasi, butuh pencarian/filter kompleks.

Tabel: catatan
Baris #1 — id, judul
Baris #2 — id, judul
Baris #3 — id, judul

Arahkan kursor ke laci → "tarik keluar" data

15SQLite

SQLite — Alur CRUD & Code

C
Create

INSERT — tambah baris baru

R
Read

SELECT — baca data

U
Update

UPDATE — ubah data

D
Delete

DELETE — hapus data

sqflite_crud.dart
final db = await openDatabase('catatan.db', version: 1,
  onCreate: (db, v) => db.execute(
    'CREATE TABLE catatan(id INTEGER PRIMARY KEY, judul TEXT, selesai INTEGER)'
  ));

// CREATE
await db.insert('catatan', {'judul': 'Belajar SQL', 'selesai': 0});

// READ
List<Map> data = await db.query('catatan');

// UPDATE
await db.update('catatan', {'selesai': 1}, where: 'id = ?', whereArgs: [1]);

// DELETE
await db.delete('catatan', where: 'id = ?', whereArgs: [1]);
16Perbandingan

SharedPreferences vs Hive vs SQLite

AspekSharedPreferencesHiveSQLite
JenisKey–Value sederhanaNoSQL (Box)Relasional (Tabel + SQL)
Cocok untukSetting, skor, flag kecilObjek/list, data sedangData banyak & berelasi
Kecepatan★★★☆☆★★★★★★★★★☆
KerumitanSangat mudahMudahMenengah (perlu SQL)

🔑 Pakai SharedPreferences bila datanya kecil & sederhana, contoh: status dark mode.

🐝 Pakai Hive bila butuh cepat menyimpan objek/list tanpa query rumit.

🗄️ Pakai SQLite bila data banyak, perlu filter/relasi & pencarian kompleks.

17Mini Project

Aplikasi Catatan Harian — Preview

Kita akan membangun aplikasi Catatan Harian yang menyimpan catatan secara permanen menggunakan Hive.

  • Tambah catatan baru
  • 📄 Lihat daftar catatan tersimpan
  • Tandai catatan selesai
  • 🗑️ Hapus catatan
  • 💾 Data tetap ada walau app ditutup
▶ DEMO: TAMBAH CATATAN KE PREVIEW
📓 Catatan Harian
Belajar Local Storage ✅
Mengerjakan tugas Flutter
Review materi JSON
+
18Mini Project

Architecture & Code Implementation

CatatanModel HiveStorage CatatanPage (UI)
catatan_model.dart
class Catatan {
  String judul;
  bool selesai;
  Catatan({required this.judul, this.selesai = false});

  Map<String, dynamic> toJson() =>
      {'judul': judul, 'selesai': selesai};

  factory Catatan.fromJson(Map<String, dynamic> j) =>
      Catatan(judul: j['judul'], selesai: j['selesai']);
}
hive_storage.dart
class HiveStorage {
  final box = Hive.box('catatanBox');

  // simpan list catatan (sudah di-serialize)
  void simpan(List<Catatan> list) {
    box.put('catatan',
      list.map((c) => c.toJson()).toList());
  }

  // baca list catatan (deserialize)
  List<Catatan> baca() {
    final raw = box.get('catatan', defaultValue: []);
    return (raw as List)
      .map((j) => Catatan.fromJson(Map.from(j)))
      .toList();
  }
}
catatan_page.dart
class CatatanPage extends StatefulWidget {
  @override
  State<CatatanPage> createState() => _CatatanPageState();
}

class _CatatanPageState extends State<CatatanPage> {
  final storage = HiveStorage();
  List<Catatan> catatan = [];

  @override
  void initState() {
    super.initState();
    catatan = storage.baca(); // muat dari Hive
  }

  void tambah(String judul) {
    setState(() => catatan.add(Catatan(judul: judul)));
    storage.simpan(catatan); // simpan permanen
  }

  void hapus(int i) {
    setState(() => catatan.removeAt(i));
    storage.simpan(catatan);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Catatan Harian')),
      body: ListView.builder(
        itemCount: catatan.length,
        itemBuilder: (_, i) => ListTile(
          title: Text(catatan[i].judul),
          trailing: IconButton(
            icon: Icon(Icons.delete),
            onPressed: () => hapus(i),
          ),
        ),
      ),
    );
  }
}
19Mini Project

Demo Flow Lengkap

Bagaimana data mengalir saat user menambah satu catatan:

1
Input User

User mengetik judul & menekan tombol ➕

2
Serialize

Object Catatan → toJson() → Map

3
Simpan

box.put() menyimpan ke Hive (disk)

4
Retrieve

box.get() + fromJson() → Object

5
Tampilkan

setState() render ulang ListView

Input Serialize Storage (Hive) Deserialize UI
20Rangkuman

Ringkasan BAB 10 — Mind Map

Klik tiap node untuk mengingat poin utamanya.

🔑 SharedPreferences
{ } JSON
LOCAL
STORAGE
🔁 Serialize
🐝 Hive
🗄️ SQLite
// klik salah satu node untuk melihat ringkasannya...
21LATIHAN 1

Quiz: SharedPreferences & JSON

1. Method yang benar untuk menyimpan String di SharedPreferences adalah…

2. Mengubah Object Dart menjadi JSON String disebut…

3. Fungsi jsonDecode() dipakai untuk…

✍️ Soal Essay: Jelaskan dengan kata-katamu sendiri perbedaan antara State (BAB 9) dan Local Storage (BAB 10). Berikan satu contoh kapan masing-masing dipakai.

22LATIHAN 2

Coding Challenge: CRUD dengan Hive

Lengkapi scaffolding di bawah ini. Isi bagian // TODO agar fungsi CRUD bekerja.

challenge.dart (lengkapi!)
final box = Hive.box('tugasBox');

// TODO 1: simpan tugas baru dengan key 'tugas1'
// _______________________________________

// TODO 2: baca tugas1, default '(kosong)'
String t = // ___________________________

// TODO 3: ubah nilai tugas1
// _______________________________________

// TODO 4: hapus tugas1
// _______________________________________
🔒 Klik kartu ini untuk melihat
KUNCI JAWABAN
1: box.put('tugas1', 'Belajar');
2: box.get('tugas1', defaultValue:'(kosong)');
3: box.put('tugas1', 'Selesai');
4: box.delete('tugas1');

🎯 Kriteria sukses: keempat operasi CRUD (Create, Read, Update, Delete) berjalan tanpa error & data tersimpan setelah app di-restart.

23TUGAS AKHIR

Mini Project Mandiri

🎯 Buat Aplikasi Catatan Harian versimu sendiri menggunakan SharedPreferences atau Hive.

KriteriaBobot
Fungsi CRUD berjalan benar40%
Data persisten (storage benar)25%
Serialization/Deserialization rapi15%
Tampilan UI & kerapian kode20%

🏆 Bonus (poin tambahan): tambahkan fitur tandai "selesai", pencarian catatan, atau pilih Hive vs SQLite dengan alasannya.

— SELAMAT BELAJAR! BAB 10 SELESAI 🎉 —