Watch the video (18 min)
On this page12 sections
  1. Prerequisites
  2. Connection With Previous Lectures
  3. Learning Objectives
  4. 1. The Manager
  5. 2. Call It From main
  6. Code Examples
  7. Common Beginner Mistakes
  8. Best Practices
  9. Mini Challenge
  10. Practice Questions
  11. Practice Answers
  12. Key Takeaways

Lecture 004 — The Manager Class

Category2 — Models & Manager
Lecture004 of 007
Estimated video length18 min
TargetFlutter 3.44 · Dart 3.12 · hive 2.2
LevelBeginner
VideoPart 1 — Introduction, Setup, Model Adapters & Manager Classes
Source codeGitHub — urraan_hive_final_code

Screens should not know how Hive works. We put every database call in one class — GeneralBox — so a screen only says "save this" or "delete that".

Contents

Prerequisites · Connection · Objectives · Lesson · Code Examples · Common Mistakes · Best Practices · Mini Challenge · Practice Questions · Answers · Takeaways


Prerequisites

Lectures 001–003: Box, put/delete, and the generated DataObjectsAdapter.


Connection With Previous Lectures

We have a model and an adapter. Someone must register the adapter, open the box, and offer add / update / delete. That someone is the manager.


Learning Objectives

  • Write an init() that starts Hive, registers the adapter and opens the box
  • Write addUpdate, delete and getUniqueKey
  • Call init() from main before runApp

1. The Manager

dart
// lib/data_hive/general_box.dart
import 'package:hive_flutter/hive_flutter.dart';

import 'data_objects.dart';

class GeneralBox {
  static const String dataObjects = 'DataObjects';

  static Future<void> init() async {
    await Hive.initFlutter();

    if (!Hive.isAdapterRegistered(DataObjectsAdapter().typeId)) {
      Hive.registerAdapter(DataObjectsAdapter());
    }
    if (!Hive.isBoxOpen(dataObjects)) {
      await Hive.openBox<DataObjects>(dataObjects);
    }
  }

  static Box<DataObjects> getBox() => Hive.box<DataObjects>(dataObjects);

  static String getUniqueKey() =>
      DateTime.now().millisecondsSinceEpoch.toString();

  static bool addUpdate(DataObjects item) {
    final box = getBox();
    box.put(item.key, item);
    return box.containsKey(item.key);
  }

  static bool delete(String key) {
    final box = getBox();
    box.delete(key);
    return !box.containsKey(key);
  }

  static List<DataObjects> getAll() => getBox().values.toList();
}
  • static — every member is static; screens call GeneralBox.addUpdate(...) without creating an object.
  • init() — initialise, register, open, in that order. The two if checks make it safe to call twice (for example after a hot restart).
  • getUniqueKey() — milliseconds since 1970 as text: unique enough for one user adding records by hand.
  • addUpdate — put creates the record if the key is new and replaces it if the key exists, so one method does both. It returns true when the key is present afterwards, so the screen can react to success or failure.
  • delete — same idea, true once the key is gone.

2. Call It From main

dart
// lib/main.dart
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await GeneralBox.init();
  runApp(const MyApp());
}

The box must be open before any widget calls getBox().


Code Examples

Example 1 — Using the Manager

dart
final person = DataObjects()
  ..key = GeneralBox.getUniqueKey()
  ..name = 'Zayan'
  ..address = 'Karachi'
  ..hobbies = ['Cricket'];

final saved = GeneralBox.addUpdate(person);   // true
GeneralBox.delete(person.key);                // true

The .. cascade sets several fields on the new object in one expression.


Common Beginner Mistakes

1. Calling init() without await — the app starts before the box is open and the first getBox() throws "Box not found".

2. Creating a new key on every update — updating must reuse the existing item.key, otherwise you create a copy instead of replacing. Lecture 006 handles this.

3. Opening the box with one type and reading with another — openBox<DataObjects> needs Hive.box<DataObjects>.


Best Practices

  • One manager (or one per box) — never scatter Hive.box(...) through screens.
  • Keep box names in constants.
  • Return a success bool so the UI can show a message.

Mini Challenge

Add static int count() => getBox().length; and a clearAll() that empties the box.


Practice Questions

  1. Why are the manager's members static? 2. What does isAdapterRegistered prevent?
  2. Why is addUpdate one method instead of two? 4. What must main do before runApp?

Practice Answers

  1. So no object is needed — one shared box.
  2. Registering the same adapter twice (an error).
  3. put replaces an existing key or adds a new one.
  4. await GeneralBox.init().

Key Takeaways

  • The manager owns Hive: init, register, open, add/update, delete.
  • put with the same key is an update.
  • main awaits init() before runApp.

Video lecture

Lecture 004 · 18 min