الإجابة المختصرة: ليس السؤال «هل يعمل تطبيقي بلا إنترنت؟» بل «أي جزء منه يعمل بلا إنترنت؟». والعمل دون اتصال ليس ميزة واحدة بل سبعة مستويات متدرّجة: من مجرد رسالة مهذّبة عند الانقطاع، إلى تطبيق يعمل كاملًا أيامًا ثم يزامن. واختيار المستوى الخطأ مكلف في الاتجاهين: مستوى أقل من اللازم يعني تطبيقًا يفشل حيث يُستخدم فعلًا، ومستوى أعلى من اللازم يعني تعقيدًا هندسيًا يضاعف الوقت والتكلفة بلا حاجة. والتطبيق بدون إنترنت يبدأ من سؤال واحد: أين يستخدم عميلي هذا التطبيق؟
لماذا يهمّ هذا في السوق السعودي؟
الاتصال في المدن ممتاز، لكن الاستخدام الحقيقي يحدث في أماكن أخرى: مواقف تحت الأرض، ومصاعد، ومستودعات، ومواقع إنشاء، وطرق سريعة بين المدن، ومناطق زحام تنخفض فيها جودة الشبكة.
والحالة الأشيع ليست انقطاعًا كاملًا بل شبكة سيئة: متصل ظاهريًا، ولا يصل شيء. وهذه أسوأ من الانقطاع لأن التطبيق ينتظر بلا نهاية بدل أن يتصرّف.
ومن يهمّه هذا أكثر: تطبيقات المندوبين والفنيين، وتطبيقات المستودعات والجرد، وتطبيقات نقاط البيع، وأي تطبيق ميداني يُستخدم خارج المكتب.
المستوى 1: إخبار المستخدم بأدب
أدنى مستوى مقبول: التطبيق يكتشف الانقطاع ويقول ذلك بوضوح بدل أن يعلق أو يعرض خطأ غامضًا.
ما يجب أن يتضمنه: رسالة مفهومة، وزر «إعادة المحاولة»، ومهلة انتظار معقولة لا انتظار مفتوح.
وهذا الحد الأدنى يجب أن يوجد في كل تطبيق مهما كان، لأن الانقطاع يحدث للجميع.
المستوى 2: عرض ما سبق تحميله
التطبيق يحفظ آخر بيانات جلبها، ويعرضها عند الانقطاع مع إشارة واضحة إلى أنها محفوظة.
مثال: تطبيق مطاعم يعرض آخر قائمة رآها المستخدم، مع تنبيه أن الأسعار قد تكون تغيّرت.
والمكسب المزدوج: هذا يسرّع الفتح أيضًا حتى مع وجود اتصال، وهو ما شرحناه في حجم التطبيق وسرعة الإقلاع.
المستوى 3: القراءة الكاملة دون اتصال
التطبيق ينزّل ما يحتاجه المستخدم مسبقًا: قائمة المنتجات، أو جدول المواعيد، أو دليل الإجراءات.
مناسب لـ: التطبيقات التي محتواها لا يتغيّر كل دقيقة. والمستخدم يتصفّح كل شيء بلا اتصال، ولا يحتاج الشبكة إلا للعمليات.
والقرار المهم هنا: ماذا تنزّل ومتى؟ التنزيل المسبق لكل شيء يستهلك باقة المستخدم ومساحته. اجعله ذكيًا: ما يخصّه هو، وعند وجود اتصال جيد.
المستوى 4: الكتابة في الطابور
المستخدم ينفّذ عملية بلا اتصال، فتُحفظ محليًا وتُرسَل تلقائيًا عند عودة الشبكة.
مثال واقعي: فنّي صيانة يسجّل إنجاز مهمة في قبو بلا تغطية. العملية تُحفظ، ويرى «بانتظار الإرسال»، وترسل نفسها لاحقًا.
وهنا يبدأ التعقيد الحقيقي. يجب أن تعالج: ماذا لو فشل الإرسال؟ وماذا لو أغلق التطبيق قبل المزامنة؟ وكيف يعرف المستخدم حالة كل عملية؟
القاعدة: أظهر الحالة دائمًا. «محفوظ محليًا» و«جارٍ الإرسال» و«تم» — ثلاث حالات مرئية تمنع أسئلة كثيرة.
المستوى 5: المزامنة ثنائية الاتجاه
التطبيق يرسل تغييرات المستخدم ويستقبل تغييرات الآخرين، ويوفّق بينها.
وهنا تظهر مشكلة التعارض: موظفان عدّلا السجل نفسه وكلاهما دون اتصال. أيهما يفوز؟
استراتيجيات معتادة: الأحدث يفوز (بسيطة وقد تفقد بيانات)، أو الدمج على مستوى الحقول (أدق وأصعب)، أو عرض التعارض للمستخدم ليختار (أوضح وأثقل على التجربة).
والاختيار يعتمد على طبيعة البيانات: حالة طلب لا تحتمل الخسارة، وملاحظة نصية قد تحتمل الدمج.
المستوى 6: العمل الكامل لفترات طويلة
التطبيق يعمل أيامًا دون اتصال بقاعدة بيانات محلية كاملة، ثم يزامن.
مناسب لـ: الجرد الميداني، والمسوح، والعمل في مواقع نائية.
وتكلفته عالية: يحتاج تصميم قاعدة بيانات محلية، ونظام مزامنة، ومعالجة تعارض، واختبارات مطوّلة. لا تختره إلا إذا كان جوهر الاستخدام.
المستوى 7: أولوية العمل المحلي دائمًا
أعلى مستوى: التطبيق يكتب محليًا أولًا دائمًا ويقرأ محليًا دائمًا، والشبكة مجرد مزامنة في الخلفية.
النتيجة: تطبيق سريع جدًا لا يتوقف أبدًا، لأن المستخدم لا ينتظر الشبكة في أي عملية.
والثمن: أعقد بنية ممكنة، وتحتاج فريقًا مجرّبًا. لكنها الخيار الصحيح لتطبيقات الملاحظات والمهام والأدوات اليومية.
جدول: أي مستوى لأي تطبيق؟
| نوع التطبيق | المستوى المناسب | |—|—| | تطبيق تعريفي أو محتوى | 1–2 | | متجر إلكتروني | 2–3 | | حجز مواعيد | 2–3 | | توصيل (جهة العميل) | 2–3 | | توصيل (جهة المندوب) | 4–5 | | صيانة ميدانية | 4–6 | | جرد ومستودعات | 5–6 | | نقاط بيع | 6–7 | | ملاحظات ومهام | 7 |
كيف تقرّر؟ ثلاثة أسئلة
أين يُستخدم التطبيق فعلًا؟ ليس أين تتخيّل، بل أين يقف المستخدم حين يفتحه. اسأل خمسة مستخدمين حقيقيين.
ما أسوأ ما يحدث عند الانقطاع؟ إن كان «يؤجّل المستخدم مهمته دقيقة» فالمستوى منخفض يكفي. وإن كان «يخسر عمل ساعة» أو «تتوقف عملية بيع»، فأنت في المستويات العليا.
كم يحتمل المشروع من تعقيد؟ كل مستوى فوق الرابع يضيف وقتًا واختبارًا وصيانة. وهذا ينعكس مباشرة على تكلفة تصميم تطبيق وعلى مدته.
كيف تُبنى المزامنة عمليًا؟
أربعة عناصر تتكرّر في كل نظام مزامنة ناجح، مهما اختلفت التقنية:
طابور عمليات محلي. كل عملية يجريها المستخدم تُسجَّل كطلب مؤجّل بترتيبها. والترتيب مهم: إن أنشأ عنصرًا ثم عدّله، فالإرسال بترتيب معكوس يفشل.
معرّف يولّده الجهاز. لا تنتظر الخادم ليعطيك رقمًا. ولّد معرّفًا محليًا فريدًا، واربطه بمعرّف الخادم عند المزامنة. بلا هذا، لا يستطيع المستخدم إنشاء عنصر ثم استخدامه فورًا.
إعادة محاولة بتباعد متزايد. فشل الإرسال مرة لا يعني الاستسلام ولا التكرار كل ثانية. أعد بعد ثوانٍ، ثم دقيقة، ثم أطول — وتوقّف عند حدّ معقول مع إبلاغ المستخدم.
علامة زمنية أو رقم نسخة لكل سجل. بها يعرف الخادم ما تغيّر منذ آخر مزامنة، فلا يُرسل كل شيء في كل مرة.
والعنصر الخامس غير التقني: قرار مكتوب لما يحدث عند التعارض. اتخذه مبكرًا وسجّله، فهو أكثر ما يُختلف عليه لاحقًا حين تظهر الحالة أول مرة في الإنتاج.
أخطاء متكررة
افتراض أن الاتصال ثنائي. الواقع ثلاث حالات: متصل، ومنقطع، ومتصل بشبكة سيئة. الحالة الثالثة هي الأخطر، وتحتاج مهلة انتظار ومحاولات إعادة.
إخفاء حالة المزامنة. المستخدم لا يعرف إن كان عمله محفوظًا. اجعل الحالة مرئية دائمًا.
عدم اختبار الانقطاع. فعّل وضع الطيران أثناء عملية، وأثناء رفع صورة، وبين خطوتين — وستجد أعطالًا لم تخطر ببالك.
تجاهل حدود التخزين. التطبيق الذي يحفظ كل شيء محليًا ينتفخ حتى يُحذف. ضع سقفًا وسياسة تنظيف.
نسيان الأمان. البيانات المحفوظة على الجهاز تحتاج حماية، خصوصًا إن كانت حساسة. لا تحفظ ما لا يلزم.
حالة عملية: تطبيق فنّي صيانة
لنجمع كل ما سبق في مثال واحد نراه كثيرًا في المشاريع الميدانية.
الاستخدام الفعلي: الفنّي يستقبل مهامه صباحًا، ثم يعمل طوال اليوم في مواقع متفرقة — بعضها في أقبية أو مبانٍ تحت الإنشاء بلا تغطية.
القرار: المستوى الرابع إلى الخامس. القراءة كاملة دون اتصال، والكتابة في طابور، ومزامنة عند عودة الشبكة.
كيف يُترجم إلى تصميم؟
عند بدء اليوم — التطبيق ينزّل مهام اليوم كاملة ببياناتها: العناوين، وأرقام العملاء، وسجل الجهاز، والقطع المتوقعة. هذا يحدث على شبكة جيدة في المكتب أو المنزل.
أثناء العمل — كل شيء يُقرأ محليًا فورًا. والفنّي يسجّل: وصلت، بدأت، القطع المستخدمة، صورة الإنجاز، توقيع العميل. كلها تُحفظ محليًا بحالة «بانتظار الاتصال».
عند عودة الشبكة — الطابور يُرسل بالترتيب، والصور بأولوية أدنى من البيانات النصية حتى لا تعطّلها.
والحالة الحرجة: ماذا لو نفد شحن الجهاز قبل المزامنة؟ لهذا تُحفظ العمليات في تخزين دائم لا في الذاكرة — تفصيلة تقنية صغيرة تفصل بين نظام موثوق وآخر يخسر عمل يوم كامل.
والنتيجة التي يراها العميل: فنّي لا يقول «الشبكة ضعيفة، سأسجّلها لاحقًا» — وهذه الجملة تحديدًا هي مصدر أغلب الأخطاء في السجلات الميدانية.
أسئلة شائعة
هل كل تطبيق يحتاج عملًا دون اتصال؟
كل تطبيق يحتاج المستوى الأول على الأقل. أما ما فوقه فيقرّره الاستخدام الفعلي لا الطموح.
هل يزيد هذا التكلفة كثيرًا؟
المستويات 1–3 زيادة بسيطة تستحقها دائمًا. من 4 فما فوق تبدأ الزيادة الحقيقية، وقد تضاعف زمن أجزاء من المشروع.
كيف أختبر العمل دون اتصال؟
وضع الطيران، وشبكة مقيّدة عمدًا، وقطع الاتصال في منتصف العملية لا قبلها. والحالة الأخيرة هي التي تكشف أغلب الأعطال.
ما الفرق بين التخزين المؤقت والعمل دون اتصال؟
التخزين المؤقت يسرّع القراءة، والعمل دون اتصال يتيح الكتابة أيضًا. كثير من التطبيقات تظن أنها تدعم الثاني وهي تفعل الأول فقط.
هل أعرض مؤشر «غير متصل» دائمًا؟
اعرضه حين يؤثر ذلك على ما يفعله المستخدم الآن، لا شريطًا دائمًا يقلق بلا سبب. والأهم أن تخبره بما يستطيع فعله رغم الانقطاع.
هل يمكن إضافة العمل دون اتصال لتطبيق قائم؟
ممكن للمستويات الأولى (العرض والقراءة) بجهد معقول. أما المستويات العليا فتمسّ بنية التطبيق كلها وقد تعني إعادة كتابة طبقة البيانات — ولهذا يُتخذ القرار مبكرًا لا بعد عامين.
ماذا عن الصور والملفات؟
هي أثقل ما يُزامَن. أرسلها في الخلفية بأولوية أدنى من البيانات، واضغطها قبل الرفع، وأتح للمستخدم متابعة ما تبقّى.
هل أسمح للمستخدم بتعطيل المزامنة التلقائية؟
مفيد في التطبيقات التي تنقل بيانات كثيرة، خصوصًا لمن يستخدم باقة محدودة. أتِح خيار «المزامنة على الواي فاي فقط»، لكن لا تجعله الافتراضي — وإلا فوجئ المستخدم ببيانات قديمة.
كيف أتعامل مع تحديث التطبيق وبيانات محفوظة بصيغة قديمة؟
عبر ترقية منظمة لبنية التخزين المحلي عند أول تشغيل بعد التحديث. وإهمال هذه النقطة سبب معروف لانهيار التطبيق بعد التحديث لدى المستخدمين القدامى دون الجدد.
هل المزامنة تستهلك البطارية؟
إن كانت متكرّرة بلا داعٍ نعم. زامن عند تغيّر الحالة أو عند عودة الاتصال أو بفواصل معقولة — لا كل بضع ثوانٍ.
ماذا يرى المستخدم؟ لغة الحالات
الجانب الأصعب في العمل دون اتصال ليس التقنية بل إفهام المستخدم ما يجري. وهذه لغة حالات واضحة تصلح لأغلب التطبيقات:
«محفوظ على جهازك». العملية تمت محليًا ولن تضيع. «بانتظار الاتصال». ستُرسل تلقائيًا حين تعود الشبكة. «جارٍ الإرسال». المزامنة تعمل الآن. «تم». وصلت وأُكّدت من الخادم. «فشل الإرسال». مع سبب وزر إعادة محاولة.
وأربع قواعد لعرضها:
اجعلها على مستوى العنصر لا التطبيق. المستخدم يريد معرفة حالة طلبه هذا، لا حالة عامة.
لا تدّعِ النجاح مبكرًا. «تم» قبل تأكيد الخادم كذبة ستنكشف، وهي أسوأ من الانتظار.
اعرض عدّادًا للمعلّق. «3 عمليات بانتظار الإرسال» يطمئن ويشرح.
واسمح بالتدخّل. زر «أرسل الآن» يعطي المستخدم إحساسًا بالسيطرة، وينفع فعلًا حين يعرف أن الشبكة عادت قبل أن يكتشفها التطبيق.
اسأل مستخدميك أين يقفون
قبل اختيار المستوى، اتصل بخمسة من مستخدميك الحاليين واسأل سؤالًا واحدًا: أين كنت آخر مرة فتحت فيها التطبيق؟
الإجابات ستفاجئك غالبًا: في السيارة، وفي مصعد، وفي مستودع، وأثناء انتظار في طابور. وهذه الأماكن — لا مكتبك — هي البيئة الحقيقية لتطبيقك.
والقرار الهندسي يُبنى على هذه الإجابات لا على تصوّر الفريق لكيفية استخدام منتجه.
الخلاصة: العمل دون اتصال قرار منتج لا قرار تقني. والمستوى الصحيح يأتي من مكان واحد: أين يقف مستخدمك حين يفتح التطبيق. تطبيق العميل في بيته يحتاج مستوى، وتطبيق الفنّي في قبو مبنى يحتاج آخر تمامًا — وبناء الثاني بعقلية الأول يعني منتجًا يفشل في اللحظة التي وُجد لأجلها. ونحن نبدأ كل مشروع ميداني بهذا السؤال في شركة تصميم تطبيقات الجوال.
