I'm always excited to take on new projects and collaborate with innovative minds.

Phone

+20 115 052 9992

Website

https://ibrahimahmed.online/

Social Links

إزاي تبني تطبيق موبايل Offline-First باستخدام Flutter و Drift و Hive

إزاي تبني تطبيق موبايل Offline-First باستخدام Flutter و Drift و Hive أكيد مريت بالموقف ده، بتطور تطبيق فلاتر (Flutter) وزي الفل، وفجأة المستخدم يدخل في الأسانسي

إزاي تبني تطبيق موبايل Offline-First باستخدام Flutter و Drift و Hive
Reading Count: 4

إزاي تبني تطبيق موبايل Offline-First باستخدام Flutter و Drift و Hive

أكيد مريت بالموقف ده، بتطور تطبيق فلاتر (Flutter) وزي الفل، وفجأة المستخدم يدخل في الأسانسير أو شبكة الموبايل تقع، والتطبيق يفتح شاشة "مفيش إنترنت" واليوزر يقفل التطبيق بزهق. النهاردة هنتكلم عن الحل السحري اللي بيخلي تطبيقاتك تعيش وتتنفس بدون إنترنت، وهو معمارية (Offline-First Architecture).

يعني إيه Offline-First وليه الموبايل محتاجه؟

معمارية (Offline-First) ببساطة هي إن التطبيق بتاعك بيعتمد على قاعدة البيانات المحلية كأنها المصدر الأساسي (Source of Truth)، والإنترنت بيجي دوره عشان "يحدث" البيانات دي في الخلفية. ميزة النهج ده إن التطبيق دايماً شغال، سريع جداً في الاستجابة، والمستخدم مش بيحس بأي تأخير.

أدواتك في الرحلة دي: Hive و Drift

عشان نطبق المبدأ ده في (Flutter)، هنحتاج اتنين من أتقل الأدوات:

  • Hive: قاعدة بيانات (Key-Value) خفيفة جداً وسريعة، ممتازة لتخزين الـ (User Settings) أو البيانات اللي حجمها بسيط.
  • Drift: هي المكتبة رقم 1 لو عايز تتعامل مع (SQLite) في فلاتر بشكل احترافي، بتديك (Type-safety) رهيب وتسهل عليك التعامل مع الجداول المعقدة.

خطوات تنفيذ الـ Sync Strategy

عشان تعمل (Synchronization) مظبوط، محتاج تتبع المنهج ده:

  1. Local Storage: أي عملية إضافة أو تعديل بتسمع الأول في (Drift) فوراً.
  2. Flagging: ضيف عمود (Column) في جدولك اسمه is_synced، بياخد قيمة (Boolean). لما اليوزر يعدل حاجة والنت قاطع، بتخلي قيمته (false).
  3. Background Sync: استخدم مكتبة زي (Connectivity Plus) عشان تراقب حالة النت. بمجرد ما يرجع، اعمل (Loop) على كل الصفوف اللي is_synced = false وابعتهوم للسيرفر.

كود عملي: مثال بسيط لـ Drift

ده شكل مبسط لتعريف جدول في (Drift) بيراعي حالة المزامنة:


class Todos extends Table {
  IntColumn get id => integer().autoIncrement()();
  TextColumn get content => text()();
  BoolColumn get isSynced => boolean().withDefault(const Constant(false))();
}

بعد ما بتعمل العملية، بتحدث الحالة في قاعدة البيانات المحلية:


Future syncDataToServer() async {
  final pendingItems = await select(todos)..where((t) => t.isSynced.equals(false));
  for (var item in await pendingItems.get()) {
    final response = await api.upload(item);
    if (response.success) {
      update(todos)..where((t) => t.id.equals(item.id))..write(TodosCompanion(isSynced: Value(true)));
    }
  }
}

إدارة الـ State مع Hive للبيانات المؤقتة

مش كل حاجة محتاجة (SQLite)، لو عندك بيانات زي "حالة تسجيل الدخول" أو "تفضيلات المستخدم"، استخدم (Hive):

final box = Hive.box('user_settings'); box.put('theme', 'dark');

خلاصة الكلام: نصيحة من أخ

بناء معمارية (Offline-First) هو اللي بيفرق بين المبرمج "الهاوي" والمحترف. اه الموضوع بياخد وقت أطول في التخطيط، لكن تجربة المستخدم (UX) اللي بتقدمها بتبقى خرافية. ابدأ دايماً بتصميم قاعدة البيانات المحلية، وماتخليش الاعتماد على الـ (API) هو أساس التطبيق. اتعلم تقنيات الـ (Data Sync Conflict Resolution) عشان تتفادى المشاكل لما نفس البيانات تتعدل من مكانين في نفس الوقت.


Share

Related posts

Jul 01, 2026 • 1 min read
Reading Count: 4
إزاي تتجنب تسريب الذاكرة (Memory Leaks) في تطبيقات Vue 3 وتخلي موقعك طيارة

إزاي تتجنب تسريب الذاكرة (Memory Leaks) في تطبيقات Vue 3 وتخلي موقعك طيارة أكيد مريت بالموقف ده قبل...

Jul 01, 2026 • 1 min read
Reading Count: 9
إزاي تعمل إضافة لمتصفح جوجل كروم (Chrome Extension) باستخدام React و Tailwind CSS؟

إزاي تعمل إضافة لمتصفح جوجل كروم (Chrome Extension) باستخدام React و Tailwind CSS؟ كتير مننا كمبرمجي...

Jun 30, 2026 • 1 min read
Reading Count: 9
دليلك الاحترافي للـ Subqueries المعقدة في Laravel Eloquent

دليلك الاحترافي للـ Subqueries المعقدة في Laravel Eloquent أكيد مريت بالموقف ده: عندك جدول للطلبات (...