كثيرٌ منّا يعمل على تطبيقات Flutter ويشعر أنّه يعمل داخل عالمٍ منفصل؛
نكتب Dart ، نبني واجهات المستخدم ، نربط BLoC أو Provider ، ويعمل التطبيق بسلاسة…
لكن هل يعني ذلك فعلًا أنّ التطبيق يعمل دون أي كود Native؟
هدف جلستنا اليوم هو أن نفهم كيف يُستخدم Flutter في التطبيقات الحقيقية (Production) ، وكيف يتعاون مع Native بدلاً من ان يكون منفصل عنه.
بتاريخ 24 كانون الثاني 2026 تم تقديم جلسة مميزة وملهمة بعنوان هذا المقال ضمن جلسات Mobile Dev Meetups ، في مركز سند التنموي ، مع المهندسة ليلى مطر
التي سلطت الضوء على كيفية عمل و تكامل flutter مع Native كود في Android و iOS .
المقدمة :
بدأت المهندسة ليلى الجلسة بسؤال بسيط،
من منكم عمل على تطبيق Flutter دون ان يكتب بنفسه أي كود Kotlin أو Swift؟
وهنا ظهرت النقطة المهمة:
حتى لو عملنا على تطبيق Flutter فقط،فغالباً التطبيق ليس بدون Native فعلياً.
لماذا؟
لان أغلب التطبيقات الحقيقية تحتاج خصائص مرتبطة بالنظام نفسه،
وFlutter لوحده لا يستطع ان ينفذها بدون Native.
الفهرس :
1-الفرق بين Package vs Plugin
2-مثال على تكامل Flutter مع الكود الأصلي (Native) في تطبيقات Production
3-نظرة عامة على بنية Flutter
4-ماهو الفرق Flutter Lifecycle vs OS Lifecycle
5- ما هو Platform Channels ؟
6-ماهي Flavors ؟
7-لماذا نحتاج Flavors ؟
8-ماهي الاشياء التي تختلف بين Flavor وFlavor؟
9- كيف نعّرف Flavors في Android و IOS؟
10-كيف يعرف Flutter أي Flavor يعمل؟
11-كيف يمكن تغيير أيقونة التطبيق التابعة ل environment ما عندما نستخدم Flavor؟
12-مفهوم Background Services
13- Deep Linking ما هو هذا المفهوم ؟
أولاً : الفرق بين Package vs Plugin:

Package :
● مكتوب بـ Dart فقط
● مسؤول عن:
UI , منطق التطبيق , State Management
● ليس له أي تعامل مباشر مع النظام
مثل:
provider، bloc، http
Plugin
هو Package، لكن:
● يحتوي كود Native :كوتلن او سويفت
● يتعامل مع خصائص النظام عن طريق Platform Channels
مثل:
camera، firebase_messaging، geolocator
الخلاصة :
كل Plugin هو Package
لكن ليس كل Package هو Plugin
ولو لم نكتب كود Native بأنفسنا، نحن فعلياً نستخدم Native من خلال Plugins.
ثانياً: نوضح الان مثال على تكامل Flutter مع الكود الأصلي (Native) في تطبيقات Production، وبالتحديد يوضّح:
كيف يكون Flutter مسؤولاً عن الواجهة والمنطق، بينما يتولّى Native التعامل مع خصائص النظام.
تطبيق توصيل طلبات:

في هذا التطبيق نرى ان الواجهة Flutter:
● الصفحة الرئيسية
● قائمة المطاعم
● شاشة تتبع الطلب
● كل الـ UI
والميزات المرتبطة بالنظام Native:
● تحديث الموقع في الخلفية
● استقبال الاشعارات
● فتح التطبيق من رابط في رسالة (SMS) Deep Linking
● خدمة تعمل بالخلفية لتتبع السائق
كمطوّر Flutter:
● كل عملك هو Dart
● تستخدم Plugins
التطبيق يعمل بشكل طبيعي ولكن خلف الكواليس:
يوجد كود Native يعمل و يوجد تواصل مباشر مع النظام
ثالثاً : نظرة عامة على بنية Flutter

لنفهم لماذا التكامل بين Flutter وNative ضروري، من خلال بنية Flutter نفسها
:Flutter
● لا يستخدم مكونات UI الاصلية
● ولا يعتمد على WebView
● يرسم كل شيء بنفسه باستخدام محرك رسم خاص فيه
البنية بشكل مبسط تكون كالتالي:
Flutter UI (Dart)
↓
Flutter Engine
↓
Platform Embedder
↓
Android / iOS
لنشرح كل واحدة بشكل مبسط :
أولاً: طبقة واجهة المستخدم UI في Flutter (Dart)
هذه الطبقة التي نعمل بها كمطّورين يومياً
فيها:
● الشاشات
● الـ Widgets
● الـ State
● منطق التطبيق
نكتب هنا :
أريد زر، أريد نص،أريد صفحة
وهذه الطبقة لا تتعامل مباشرةً مع النظام.
ثانياً: Engine Flutter
هذا هو المحرك الذي يستقبل طلبات الواجهة ويرسمها.
وظيفته:
● يرسم الواجهة
● يدير الانيميشن
● يتعامل مع اللمس
● ويقوم بتشغيل كود Dart
ببساطة:
Flutter UI يطلب وEngine Flutter ينفذ ويرسم
ثالثاً :Platform Embedder
هذه طبقة الربط بين Flutter والنظام.
دورها:
● توصل Flutter مع Android أو iOS
● تمرر أحداث مثل :
دورة حياة التطبيق (Lifecycle) أو أحداث اللمس والتفاعل مع الشاشة أو تغيّر حجم الشاشة أو اتجاهها
● وتنفذ Platform Channels التي نعتبرها المترجم بين Flutter والنظام.
أخيرا: iOS / Android ( نظام التشغيل)
وهذا هو النظام نفسه, هو المسؤول عن:
● تشغيل وإيقاف التطبيق
● الصلاحيات
● المهام في الخلفية
● الوصول للهاردوير مثل GPS والكاميرا
رغم إن Flutter يرسم الواجهة بالكامل،الا أن النظام هو صاحب القرار النهائي.
بهذا الشكل نفهم:
● Flutter مسؤول عن الواجهة
● Native مسؤول عن النظام
● والتكامل بينهم هو الذي يجعل التطبيق يعمل بشكل صحيح في الواقع.
رابعاً : ماهو الفرق Flutter Lifecycle vs OS Lifecycle
نعلم ان Flutter لديه lifecycle مثل initState و dispose وهذا صحيح.
لكن يوجد فرق مهم:
Flutter lifecycle
● خاص بالـ widgets والواجهة
● متى الـ widget ينشأ أو ينحذف
OS lifecycle
● متى يذهب التطبيق للخلفية
● متى يعود
● متى يقرر النظام أن يوقفه
في Flutter هذا المستوى:
● يستقبل تنبيه أو signal من النظام
● يعرف إن الحالة تغيرت
● لكن لا يستطيع التحكم بالقرار
أي: Flutter يعرف لكن النظام هو من يقرر.
لماذا نحتاج Native ؟
يوجدأشياء Flutter لا يستطيع فعلها لوحده، مثل:
● تشغيل Service Background حقيقي
● الاستمرار بعد اغلاق التطبيق
● تسجيل Deep Linksعلى مستوى النظام
عندما نحتاج هذه الميزات و أشياء أخرى، يجب أن نعود ل Native كود
خامساً : ما هو Platform Channels
Platform Channels هي جسر التواصل بين Flutter وNative.
يمكن ان نعتبرها مترجم:
● Flutter يتكلم Dart
● Android يتكلم Kotlin
● iOS يتكلم Swift
سواء كتبنا Native بأنفسنا أو استخدمنا Plugin جاهز، Platform Channels هي التي تجعل التواصل ممكن.
الان ننتقل للأمثلة العملية، ونبدأ بأول موضوع: Flavors وكيف نستخدمها في التطبيقات الحقيقية.
Flavors في Flutter – تطبيق واحد بأكثرمن بيئة
Flavors من أول الأشياء التي تفرق بين تطبيق تجريبي وتطبيق جاهز للرفع على المتجر.
سادساً : ماهي Flavors ؟
Flavors معناها ان يكون عندنا نفس التطبيق لكن بأكثر من نسخة،
وكل نسخة مربوطة ببيئة مختلفة.
أشهر البيئات هي:
Development ●
Staging / QA ●
Production ●
الكود واحد، لكن الاعدادات تختلف
سابعاً : لماذا نحتاج Flavors ؟

لا يجوز:
● تجريب ميزة جديدة على تطبيق ال PRODUCTION
● أو ربط تطبيق تجريبي على API حقيقي
● أو ارسال إشعارات حقيقية من نسخة اختبار
وفي بعض الأحيان يوجد لدينا تطبيقين بنفس الميزات ولكن في كل دولة نريد طرحه بألوان و ايقونة مختلفة
لذلك : Flavors ليست خيار بل هي ضرورة في أي تطبيق حقيقي
ثامناً : ماهي الأشياء التي تختلف بين Flavor وFlavor؟
غالباً الاختلاف يكون في:
Base URL لل APi
اسم التطبيق
أيقونة التطبيق
Firebase Project
Logging
Feature flags
لكن:
● الكود نفسه
● الواجهة نفسها
يعني: تطبيق واحد – بإعدادات مختلفة
مثال : لدينا تطبيق اسمه MyApp

MyApp Staging●
API: Staging.api.com
أيقونة مختلفة و مخصص للتجارب
MyApp ●
API: api.com
للمستخدم النهائي
نرى تطبيقين مختلفين،لكننا كمطّورين نعمل على مشروع واحد.
نقطة مهمة: Flavors ليستonly-Flutter
:Flavors
● موجودة في Android
● وموجودة في iOS
:Flutter
● لا يخترعها
● هو فقط يستفيد منها
يعني:
الاعدادات الاساسية تكون Native وFlutter يقرأ القيم ويعمل بناءً عليها.
تاسعاً : كيف نعّرف Flavors في Android و IOS؟
ضمن Android
Android – build.gradle

هنا :
● عرفنا dev و prod
● قمنا بتغيير اسم التطبيق
● اصبح لدينا أكثر من نسخة للتطبيق
ضمن ios
في iOS الموضوع مختلف شوي.
ننشئ:
● أكثر من Scheme
● وكل Scheme مربوطة بـ Configuration Build
مثلا
Dev Scheme ●
Prod Scheme ●




ونضيف قيمة الـ Flavor في iOS – Info.plist
>key>FLAVOR</key< >string>dev</string<
وتتغّير القيمة حسب الـ Scheme.
عاشراً : كيف يعرف Flutter أي Flavor شّغال؟
Flutter – Dart
} enum AppFlavor { dev, prod
{ class FlavorConfig
;static late AppFlavor flavor
}
وفي main)(:
{ )(void main
;FlavorConfig.flavor = AppFlavor.dev
;))(runApp(MyApp
}
”هكذا Flutter اصبح يعرف ان كنا على dev أو prod.”
استخدام Flavors داخل التطبيق
{ String get baseUrl
{ )switch (FlavorConfig.flavor
:case AppFlavor.dev
;'return 'https://dev.api.com
:case AppFlavor.prod
;'return 'https://api.com
}
}
” الكود نفسه ولكن السلوك يتغّير حسب الـ Flavor.”
احدى عشر : كيف يمكن تغيير أيقونة التطبيق التابعة ل environment ما عندما نستخدم Flavor؟
Static App Icon By Flavor (أيقونة ثابتة لكل بيئة)
عندما نستخدم flavor من اجل عدة environment يجب ان يكون لكل واحدة ايقونة مختلفة حتى يفرق بينهم ال quality assurance
وفي هذه الحالة بالنسبة ل android سيكون عندنا فولدر لكل environment مثلاً في حالة ال dev نرى مجلد ال res
داخل:
src/dev/res
نضع:
- mipmap-hdpi
- mipmap-mdpi
- mipmap-xhdpi
- mipmap-xxhdpi
- mipmap-xxxhdpi
وكلها تحتوي على أيقونة التطبيق الخاصة بـ dev.
وبالمثل:
src/prod/res
تحتوي على أيقونة الإنتاج.
اما بالنسبة لل ios : نقوم بعمل section (App Icon Set) لكل environment نريد قراءتها، ثم نربط كل section بالـ Build Configuration المناسبة.
نقوم بإنشاء App Icon Set منفصل لكل environment نريد أن يقرأه التطبيق.
أي:
- AppIcon-dev
- AppIcon-prod
(ويمكن إضافة staging إن وُجد)
كل App Icon Set يمثل section مستقلة داخل:
Assets.xcassets
لماذا نعمل section لكل environment؟
لأن iOS لا يغيّر الأيقونة بناءً على اسم الـ flavor تلقائيا، بل:
- يقرأ اسم App Icon Set المربوط بالـ Build Configuration.
- وكل environment لها Build Configuration مختلفة.
بالتالي:
- Debug-dev يقرأ AppIcon-dev
- Release-prod يقرأ AppIcon-prod
كيف تتم القراءة؟
iOS لا “يكتشف” الـ environment بنفسه، بل:
- Xcode يحدد أي App Icon Set يتم استخدامه.
- عند بناء التطبيق، النظام يقرأ الأيقونة من الـ section المحدد.
Flutter هنا لا يتدخل إطلاقا.

ببعض الاحيان وخارج موضوع flavor قد نحتاج لتغيير ايقونة التطبيق في event معين مثل رمضان او عيد الاضحى
نستطيع تغييرها في ال store ولكن عندا سنضطر الزبائن لتحديث التطبيق
ولكن اذا كنا نريد وفق رغبة فريق الماركتينغ ان يتم تحديث الايقونة فورا عند الزبائن و دون الطلب منهم ان يقوموا بالتحديث سنقوم بالتالي
ضمن ال ios :سنستخدم فانكشن setAlternateIconName هذا الفانكشن يمكننا من تغيير ايقونة التطبيق ولكن بشرط وجود ال set التابعة ل event الحالي اي صورة الايقونة التابعة لرمضان مثلا يجب ان تكون مخزنة من قبل
ويحب تمرير اسم ال set icon : ايقونة رمضان مثلاً
وكما نرى اننا استخدمنا channel هنا

ضمن ال android : لا يوجد طريقة مدعومة من غوغل ديناميكية لتغيير الايقونة وانما تحايل ليست فانكشن نظامي
وهي عن طريق اننا نستخدم Activity Areas وكل صفحة يعتبرها Activity والهدف هو وضع icons التي نريد استعمالها ضمن Activity Areas ونفس القصة هنا نضع set ضمن ال res لكل مناسبة لدينا


ان فانكشن ال android و ios يستطيعان تغيير الايقونة ديناميكيا ولكن يجب وجود تريغر من
طرف flutter
بالمختصر تغيير الايقونة يتم من طرف native و التريغر واستدعاء ال channel من طرف flutter

لنفرض جاء عيد الاضحى يتم ارسال تريغر او عن طريق التاريخ وهذا الاسم نمرره لل channel ليعرف اي صورة يجب ان يستعمل
بشرط وجود set عيد الاضحى من قبل
نطلب من اليوزر اغلاق التطبيق واعادة فتحه فنجد ان الايقونة قد تغيرت
اثني عشر : مفهوم Background Services
لماذا نعتبر دوماً ان flutter وحدها غير كافية في بعض الاحيان ؟

الأسباب المذكورة:
- لا يوجد background service في Dart.
- Timers و Futures و Isolates مرتبطة بدورة حياة التطبيق ولن تعمل عندما يكون التطبيق مغلق.
- تتوقف عند اغلاق التطبيق.
تخيل انك تعمل على تطبيق وتريد ان يعمل التطبيق بالخلفية في وقت معين لاجل alarm مثلاً
عندها ستحتاج لاستخدام background services في بعض الاحيان ستجد ان البكج الخاصة بهذا المفهوم في flutter لن تعمل في بعض الاحيان سنضطر عندها للقيام بعمل background services في ال Native
وبعد ذكر كل هذه الحالات نجد ان الفريمورك في بعض الاحيان غير كافية وهي مقيدة بدورة حياة التطبيق اما عند اغلاقه ف لم يعد له اي صلاحيات
في حالة ال Android

في حالة ال ios

ثلاثة عشر : Deep Linking ما هو هذا المفهوم ؟
عند فتح لينك ما بدايةً سيذهب الطلب للسيرفر و عندها سيقوم السيرفر بالرد بريسبونس في حال كان التطبيق مثبت على الجهاز و ان لم يكن عندها سيفتح الموقع
ولكن هنا السؤال كيف سيعرف التطبيق ان هذا اللينك تابع لهذا التطبيق ؟
الجواب هو انه لل android نرفع ملف json و لل ios سنرفع ملف اخر
النظام هو من يقوم بالجواب على سؤال ما اذا كان التطبيق موجود او لا
handle Deep Linlk in Android

handle Deep Linlk in Ios

handle Deep Linlk in Flutter


الخاتمة :
دمج Flutter مع Native ليس رفاهية، بل ضرورة في التطبيقات الواقعية التي تعمل في بيئة الإنتاج
من خلال هذه المقالة، تعلمنا أن Flutter وحده كافٍ لتطوير الواجهة والمنطق، لكنه يحتاج في بعض الاوقات إلى Native عند التعامل مع النظام مباشرة، سواء لإعدادات الخلفية، أو الإشعارات، أو الوصول إلى موارد الجهاز، أو حتى إدارة بيئات متعددة باستخدام Flavors.
وإعداد Flavors بشكل صحيح، تجعل تطبيقك أكثر مرونة واستقراراً، وتسمح لك بالتحكم الكامل في أداء وسلوك التطبيق عبر بيئات مختلفة.
في النهاية، دمج Flutter مع Native يعكس واقع تطوير التطبيقات الحديثة: لا يوجد حل واحد يناسب كل شيء، بل الجمع بين قوة Flutter وسلاسة Native هو ما يمنح التطبيقات جودة عالية، أداء سلس، وتجربة مستخدم ممتازة.
التحدي الحقيقي للمطورين هو التعرف على نقاط القوة والقيود لكل طبقة والعمل بذكاء لتقديم تطبيق يعمل بسلاسة في كل السيناريوهات. بالتالي، معرفة هذه المفاهيم ليس خياراً، بل خطوة أساسية لكل من يريد بناء تطبيق Flutter احترافي في الإنتاج.
ألبوم الصور:
اكتشاف المزيد من Mobile Dev Meetup
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.