حسام برهان

الأعضاء
  • المساهمات

    166
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • Days Won

    21

السُّمعة بالموقع

85 Excellent
  1. سنبدأ في هذا الدرس من سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms ببناء تطبيق عملي بمعايير تقنيّة عالية. حيث سنستخدم المعارف التي حصلنا عليها من الدروس السابقة في بناء تطبيق جهات اتصال بسيط لكنّه يستخدم تقنيّات ومفاهيم متقدّمة نسبيًّا. سنتناول هذا التطبيق على ثلاثة أجزاء متتالية، إليك وصف مختصر لمحتوى كلّ منها: الجزء الأوّل: شرح الغاية من التطبيق، وتوضيح فكرة نموذج المستودع Repository في بناء التطبيقات، مع بناء الهيكل العام للتطبيق، وهذا هو محتوى هذا الدرس. الجزء الثاني: تجهيز النواحي الوظيفيّة للمستودع وجعله قابلًا للاستخدام. الجزء الثالث: تنفيذ واجهتي التطبيق الرئيسية والفرعيّة الخاصّة بعرض التفاصيل. وتنفيذ عمليّة التنقّل بين الواجهتين الغاية من التطبيق وكيف يعمل فكرة التطبيق بسيطة للغاية، تتلخّص بعرض جهات اتصال موجودة مسبقًا وإمكانية البحث ضمنها، مع إمكانيّة إضافة جهات اتصال جديدة وتحريرها وحذفها. يعتمد التطبيق على وجود واجهتين. الواجهة الأولى هي الواجهة الرئيسيّة وتحتوي على قسم خاص بالبحث حسب الاسم أو الكنية عن أيّ جهة اتصال موجودة مسبقًا، بالإضافة إلى قائمة لعرض جهات الاتصال الناتجة عن عمليّة البحث، وأخيرًا زر خاص بإضافة جهات اتصال جديدة. انظر الشكل التالي الذي ينتج عند ضغط زر البحث FIND عند عدم تحديد أي معيار للبحث: عندما يقوم المستخدم بنقر زر البحث FIND دون أن يحدّد أي معيار، سيقوم التطبيق بعرض جميع جهات الاتصال الموجودة لديه، والتي ستكون في هذه النسخة من البرنامج عبارة عن بيانات وهمية موجودة ضمن ذاكرة التطبيق. أمّا عند تحديد المستخدم للاسم أو الكنيّة فسيعمل التطبيق على البحث مستخدمًا منطق AND. أمّا الواجهة الثانية، فتظهر عندما يلمس المستخدم إحدى جهات الاتصال من القائمة السابقة، حيث تعرض هذه الواجهة بيانات تفصيليّة حول جهة الاتصال هذه: الاسم والكنية ورقم الهاتف وعنوان البريد الإلكتروني والهوايات. انظر إلى الشكل التالي: من الممكن تعديل أيّ من هذه البيانات ثم ينقر المستخدم زر الحفظ لحفظها، أو أن ينقر زر الرجوع إلى الواجهة السابقة الموجود في الأعلى بجانب أيقونة البرنامج في حال لم يرغب بتعديل البيانات. كما يمكن للمستخدم أن يحذف جهة الاتصال هذه بنقره على زر الحذف Delete كما يظهر من الشكل السابق. وهذه ببساطة فكرة التطبيق. نموذج المستودع Repository عندما تكبر التطبيقات وتتنوّع المهام المطلوبة منها تبرز الحاجة لوسيلة لتنظيم العمل داخل التطبيق. في الحقيقة توجد العديد من النماذج التي تدعمها Xamarin لهذه الغاية مثل نموذج MVVM الذي يستخدم بفعالية ضمن Xamarin لتنظيم وفصل الأجزاء المسؤولة عن الواجهات عن الأجزاء المسؤولة عن منطق العمل عن تلك المسؤولة عن التعامل مع مزودات البيانات البعيدة أو المحلية باختلاف أنواعها. من النماذج التي أفضلها شخصيًّا هو نموذج المستودع Repository الذي أستخدمه على نحو واسع في جميع أنواع التطبيقات التي أعمل عليها. فهو أسلوب جميل ومنطقي ويسمح بتطوير التطبيق بشكل سلس وسريع للعمل في مختلف أنواع البيئات، وهو متوافق للعمل مع نموذج MVVM. يسمح نموذج المستودع بعزل الشيفرة البرمجيّة المسؤولة عن التعامل مع البيانات عن منطق البرنامج business logic. وفي هذا الأمر عدة فوائد من أهمّها: تنظيم البرنامج، وجعله أكثر قابليّة للفهم والتطوير. إجراء تطوير على أسلوب التعامل مع البيانات دون إجراء أي تغيير في منطق عمل البرنامج. إمكانيّة إجراء تغيير جذري لنوع الخدمة التي نستخدمها لتخزين البيانات دون تغيير يُذكر في منطق العمل. سأخوض مباشرةً في كيفية اعتماد هذا النموذج في تطبيقنا هذا. حيث سنحتاج إلى استخدام واجهة واحدة Interface مع صنف واحد يُحقّقها. لتنعش ذاكرتك حول الواجهات انظر هذا الدرس. لنبدأ الآن في بناء هذا التطبيق وذلك في الفقرة التالية. بناء التطبيق ابدأ بإنشاء مشروع جديد من النوع Blank App (Xamarin.Forms Portable) وسمّه ContactsApp ثم أبق فقط على المشروعين ContactsApp (Portable) و ContactsApp.Droid كما وسبق أن فعلنا في هذا الدرس. من نافذة مستكشف الحل Solution Explorer انقر بزر الفأرة الأيمن على المشروع ContactsApp واختر من القائمة التي ستظهر الخيار Add ثم من القائمة الفرعية الخيار New Folder لإضافة مجلّد جديد. سمّ هذا المجلّد بالاسم Entities، وبعد أن يظهر في نافذة الحل Solution Explore انقر عليه بزر الفأرة الأيمن واختر الخيار Add ومن القائمة الفرعية اختر Class. ستظهر نافذة تسمح لك بتعيين اسم لهذا الصنف. اختر الاسم Contact له. هذا الصنف هو حجر البناء الأساسي لهذا البرنامج والذي يمثّل منطق العمل فيه. احرص على جعل محتويات الملف Contact.cs كما يلي: namespace ContactsApp.Entities { public class Contact { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Tel { get; set; } public string EMail { get; set; } public string Hobbies { get; set; } public override string ToString() { return string.Concat(FirstName, " ", LastName); } } } يحتوي الصنف Contact كما يظهر من الشكل السابق على البيانات الأساسيّة التي تحتاجها أيّة جهة اتصال، بالإضافة إلى خاصيّة الهوايات Hobbies التي قد تبدو غريبة قليلًا بالنسبة لجهة اتصال. انقر مرّة أخرى بزر الفأرة الأيمن على المشروع ContactsApp ثم اختر من القائمة التي ستظهر الخيار Add ثم من القائمة الفرعية الخيار New Folder لإضافة مجلّد جديد. سمّ هذا المجلّد بالاسم Abstract، وبعد أن يظهر في نافذة الحل Solution Explore انقر عليه بزر الفأرة الأيمن واختر الخيار Add ومن القائمة الفرعية اختر New Item. ستظهر نافذة تسمح لك بتعيين نوع العنصر المراد إضافته. اختر واجهة Interface وعيّن الاسم IContactsRepository لها. واحرص على أن تكون محتويات الملف IContactsRepository.cs كما يلي: using System.Threading.Tasks; using System.Collections.ObjectModel; using ContactsApp.Entities; namespace ContactsApp.Abstract { public interface IContactsRepository { Task<ObservableCollection<Contact>> GetContactsAsync(string firstName, string lastName); Task<bool> AddContactAsync(Contact contactToAdd); Task<bool> UpdateContactAsync(Contact contactToUpdate); Task<bool> DeleteContactAsync(Contact contactToDelete); } } تُستَخدَم الواجهات عمومًا عندما نرغب بتجريد Abstraction الأمور وجعلها عموميّةً وفي ذلك فائدة كبيرة في جعل الشيفرة البرمجيّة أكثر قابليّة للفهم ولإعادة الاستخدام. وهذا سبب إضافة هذه الواجهة إلى المجلّد Abstract. لا تحتوي الواجهات على أيّة شيفرة برمجيّة كما نعلم، فكل ما تحتويه هو عبارة عن تصاريح لتوابع يجب تحقيقها ضمن أيّ صنف يرغب بتحقيق هذه الواجهة. تحتوي هذه الواجهة باختصار على العمليّات الأساسيّة التي يحتاجها تطبيقنا لإنجاز المهام المنوطة به وهي: الحصول على جهات الاتصال حسب الاسم والكنية GetContactsAsync، وإضافة جهة اتصال جديدة AddContactAsync، وتحديث جهة اتصال موجودة مسبقًا UpdateContactAsync، وحذف جهة اتصال DeleteContactAsync. أمّا سبب وجود الكلمة Async في كلّ من هذه التوابع فهو للإشارة إلى أنّه يُفترض بها أن تستخدم تقنيّة البرمجة غير المتزامنة Asynchronous Programming التي تحدثنا عنها في هذا الدرس. المثير في الأمر أنّ هذه الواجهة لا تهتم بمكان وجود البيانات أو كيفيّة الحصول عليها والتعامل معها. إنّما تهتم فقط بما يحتاجه التطبيق وبشكل مجرّد. سنكرّر الآن نفس العمليّة لإضافة مجلّد جديد ضمن المشروع ContactsApp.cs واسمه Concrete وهو الذي سيحتوي على الصنف الذي سيحقّق الواجهة IContactsRepository السابقة. انقر بزر الفأرة الأيمن على هذا المجلّد واختر Add. ومن القائمة الفرعية اختر Class. سمّ هذا الصنف بالاسم MemoryContactsRepository واحرص على أن تكون محتوياته كما يلي: using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Collections.ObjectModel; using ContactsApp.Abstract; using ContactsApp.Entities; namespace ContactsApp.Concrete { public class MemoryContactsRepository : IContactsRepository { private ObservableCollection<Contact> contacts; public MemoryContactsRepository() { contacts = new ObservableCollection<Contact>() { new Contact() { Id=1, FirstName = "Ahmad", LastName="Saeed", Tel="123456", EMail="admin@example.com", Hobbies="Swimming" }, new Contact() { Id=2, FirstName = "Mahmood", LastName="Maktabi", Tel="852136", EMail="info@example.com", Hobbies="Reading" }, new Contact() { Id=3, FirstName = "Mazen", LastName="Najem", Tel="987456", EMail="it@example.com", Hobbies="Swimming" }, new Contact() { Id=4, FirstName = "Sawsan", LastName="Hilal", Tel="741258", EMail="sales@example.com", Hobbies="Writing, Reading" }, new Contact() { Id=5, FirstName = "Musab", LastName="Aga", Tel="357159", EMail="admin@example.com", Hobbies="Sport" } }; } public async Task<ObservableCollection<Contact>> GetContactsAsync(string firstName, string lastName) { throw new System.NotImplementedException(); } public async Task<bool> AddContactAsync(Contact contactToAdd) { throw new System.NotImplementedException(); } public async Task<bool> UpdateContactAsync(Contact contactToUpdate) { throw new System.NotImplementedException(); } public async Task<bool> DeleteContactAsync(Contact contactToDelete) { throw new System.NotImplementedException(); } } } الأمر الملفت للنظر هنا أنّ بيانات جهات الاتصال موجودة ضمن هذا الصنف بالفعل وتحديدًا ضمن بانيته. وهي مخزّنة ضمن المتغيّر contacts وهو معرّف على مستوى الصنف ومن النوع العمومي ObservableCollection الذي سنتحدّث عنه في الدرس التالي. يكفي الآن أن تعرف أنّه عبارة عن مجموعة عناصرها كائنات من النوع Contact وهي تُفيد في التطبيقات التي تُستخدَم فيها البرمجة غير المتزامنة. من غير الواقعي بكل تأكيد وجود البيانات مخزّنة في الصنف بهذه الطريقة، فالمفترض أن تكون ضمن قاعدة بيانات محليّة أو بعيدة أو حتى ضمن ملف عادي. في الواقع تبرز هنا قوّة نموذج المستودع Repository في عزل أسلوب الحصول على البيانات عن البرنامج الفعلي. من الواضح أيضًا أنّ التوابع الموجودة هنا تحتوي في الحقيقة على شيفرة برمجيّة تؤدّي إلى رمي الاستثناء NotImplementedException وذلك لتذكرينا بعدم جاهزيتها بعد. سيبدو مستكشف الحل في نهاية المطاف شبيهًا بالشكل التالي: الخلاصة هذا الدرس هو المقدّمة لتطبيق جهات الاتصال الذي سنتابع بناءه على مدى الدرسين التاليين. تناولنا في هذا الدرس فكرة التطبيق الأساسيّة، وتوضيح فكرة نموذج المستودع Repository من خلال بناء واجهة تمثّله بالإضافة إلى صنف يحقّقها. سيمكننا من خلال هذا الصنف (صنف المستودع) التعامل مع بيانات موجودة ضمن ذاكرة التطبيق فقط. ورغم كون هذا الأسلوب غير واقعي، إلَّا أنّه ضروري في تبسيط الأمور وجعلها أسهل للفهم. كما أنشأنا صنف يمثّل جهة الاتصال في التطبيق. ورأينا ماهية العلاقة بينه وبين صنف المستودع، من خلال الاستدعاءات إلى التوابع الموجودة ضمن الصنف الأخير. حقوق الصورة البارزة محفوظة لـ Freepik
  2. تُعتبر التحويلات الهندسيّة Transforms من المفاهيم الرياضيّة الضروريّة في عالم البرمجة الرسوميّة. هناك ثلاثة أنواع من التحويلات الهندسيّة: الانسحاب Translation الدوران Rotation التحاكي Scale تعتمد التحويلات الهندسيّة في الأساس على المصفوفات Matrices. وهي بنى رياضيّة مهمّة تُعتبر العمود الفقري لأيّ تحويل هندسي. لحسن الحظ تبسّط Xamarin الأمر، وتجعل من استخدام التحويلات الثلاثة السابقة أمرًا يسيرًا. سنتحدث في هذا الدرس من سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms عن كلّ نوع من الأنواع الثلاثة السابقة وكيفيّة تطبيقه ضمن مثال عملي بسيط. الانسحاب Translation الانسحاب هو الانتقال دون التغيير في حجم الجسم، أو إجراء أي عمليّة تدوير له. يتم تدوير أي عنصر من الصنف VisualElement عن طريق الخاصيّتين TranslationX و TranslationY. عند إسناد قيمة موجبة للخاصيّة TranslationX فإنّ ذلك سيؤدّي إلى نقل الجسم أفقيًّا إلى اليمين (بالنسبة إلى موقعه الحالي). وعند إسناد قيمة موجبة للخاصيّة TranslationY فإنّ ذلك سيؤدّي إلى نقل الجسم عاموديًّا إلى الأسفل (بالنسبة إلى موقعه الحالي). لنبدأ باختبار هذا النوع من التحويلات. ابدأ بإنشاء مشروع جديد من النوع Blank App (Xamarin.Forms Portable) وسمّه TransformsApp، ثم أبق فقط على المشروعين TransformsApp (Portable) و TransformsApp.Droid كما وسبق أن فعلنا في هذا الدرس. بعد ذلك سنضيف صفحة محتوى تعتمد على رُماز XAML كما وسبق أن فعلنا في هذا الدرس سنسمّها TranslationPage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي: <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="TransformsApp.TranslationPage"> <StackLayout Padding="20, 10"> <Frame x:Name="frame" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" OutlineColor="Accent"> <Label Text="TEXT" FontSize="Large" /> </Frame> <Slider x:Name="xSlider" Minimum="-200" Maximum="200" Value="{Binding Source={x:Reference frame}, Path=TranslationX}" /> <Label Text="{Binding Source={x:Reference xSlider}, Path=Value, StringFormat='TranslationX = {0:F0}'}" HorizontalTextAlignment="Center" /> <Slider x:Name="ySlider" Minimum="-200" Maximum="200" Value="{Binding Source={x:Reference frame}, Path=TranslationY }" /> <Label Text="{Binding Source={x:Reference ySlider}, Path=Value, StringFormat='TranslationY = {0:F0}'}" HorizontalTextAlignment="Center" /> </StackLayout> </ContentPage> يستخدم الرماز السابق تقنية ربط البيانات التي تحدثنا عنها في هذا الدرس. حيث يتحكّم بموقع عنصر frame يحتوي على لصيقة ضمنه، وذلك عن طريق عنصري Slider. يتحكم العنصر العلوي بالانسحاب الأفقي، أمّا العنصر السفلي فيتحكم بالانسحاب الشاقولي. تتم هذه العملية من خلال ربط الخاصيّة Value من عنصر Slider المسمى xSlider بالخاصيّة TranslationX لعنصر frame. وكذلك الأمر بالنسبة لعنصر Slider المسمى ySlider حيث ترتبط الخاصية Value له بالخاصية TranslationY لعنصر frame. عدّل بانية الصنف App الموجودة في الملف App.cs لتصبح على الشكل التالي: public App() { // The root page of your application MainPage = new TranslationPage(); } نفّذ البرنامج لتحصل على خرج شبيه بما يلي: أجر بعض التجارب ولاحظ الانسيابية في هذه الحركة. الدوران Rotation يمكن تدوير أي عنصر مرئي في Xamarin وذلك بتحديد مركز الدوران وزاوية الدوران. يتم تحديد زاوية الدوران بالدرجات، وتشير القيم الموجبة لزاوية الدوران إلى الدوران باتجاه عقارب الساعة. يتم تحديد مركز دوران أي عنصر عن طريق الخاصيتين AnchorX و AnchorY له. كما يمكن تحديد زاوية الدوران من خلال الخاصيّة Rotation. إذا لم يتم تحديد قيمة للخاصيتين AnchorX و AnchorY فسيكون مركز الدوران هو نفسه مركز العنصر المرئي بشكل افتراضي. لنرى كيف يعمل ذلك عن طريق مثال بسيط. أضف إلى المشروع الحالي صفحة محتوى تعتمد على رُماز XAML كما وسبق أن فعلنا في هذا الدرس سنسمّها RotationPage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي: <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="TransformsApp.RotationPage"> <StackLayout Padding="20, 10"> <Frame x:Name="frame" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" OutlineColor="Accent"> <Label Text="TEXT" FontSize="Large" /> </Frame> <Slider x:Name="rotationSlider" Maximum="360" Value="{Binding Source={x:Reference frame}, Path=Rotation}" /> <Label Text="{Binding Source={x:Reference rotationSlider}, Path=Value, StringFormat='Rotation = {0:F0}'}" HorizontalTextAlignment="Center" /> <StackLayout Orientation="Horizontal" HorizontalOptions="Center"> <Stepper x:Name="anchorXStepper" Minimum="-1" Maximum="2" Increment="0.25" Value="{Binding Source={x:Reference frame}, Path=AnchorX}" /> <Label Text="{Binding Source={x:Reference anchorXStepper}, Path=Value, StringFormat='AnchorX = {0:F2}'}" VerticalOptions="Center"/> </StackLayout> <StackLayout Orientation="Horizontal" HorizontalOptions="Center"> <Stepper x:Name="anchorYStepper" Minimum="-1" Maximum="2" Increment="0.25" Value="{Binding Source={x:Reference frame}, Path=AnchorY}" /> <Label Text="{Binding Source={x:Reference anchorYStepper}, Path=Value, StringFormat='AnchorY = {0:F2}'}" VerticalOptions="Center"/> </StackLayout> </StackLayout> </ContentPage> يعتمد البرنامج السابق على تدوير عنصر frame يحتوي على لصيقة. سنستخدم لهذا الغرض عنصر Slider اسمه rotationSlider للتحكم بزاوية الدوران (عن طريق الربط مع الخاصية Rotation لعنصر frame). وسنستخدم أيضًا عنصري Stepper وهما anchorXStepper و anchorYStepper للتحكم بإحداثيي مركز الدوران (عن طريق الربط مع الخاصيّتين AnchorX و AnchorY لعنصر frame). لتنفيذ هذا البرنامج اذهب إلى بانية الصنف App الموجودة ضمن الملف App.cs واحرص على أن تكون على الشكل التالي: public App() { // The root page of your application MainPage = new RotationPage(); } نفّذ البرنامج لتحصل على شكل شبيه بما يلي: أجر بعض التجارب واستمتع بالبرنامج! التحاكي Scale التحاكي هو تحويل هندسي يؤدّي إلى التغيير في الأحجام. يمكن استخدام التحاكي للتحكم بأحجام العناصر المرئيّة عن طريق الخاصية Scale لها. لهذه الخاصيّة القيمة الافتراضيّة 1. عند استخدام أي قيمة أصغر من 1 يعني ذلك أنّنا سنعمل على تصغير الحجم. وعند استخدام أي قيمة أكبر من 1 يعني ذلك أنّنا سنكبّر الحجم. فمثًل القيمة 3 تعني أنّنا سنكبّر الحجم 3 مرات، وهكذا. القيمة 0 للخاصيّة Scale مسموحة ولكن ستؤدّي إلى اختفاء العنصر. كما يمكن استخدام القيم السالبة للخاصيّة Scale ولكن سيؤدّي ذلك إلى قلب العنصر مع بقاء المفهوم السابق على ما هو عليه. أي أنّ القيمة -1 ستؤدّي إل قلب العنصر لكن مع بقاء الحجم نفسه. لتجربة التحاكي أضف إلى المشروع الحالي صفحة محتوى تعتمد على رُماز XAML كما وسبق أن فعلنا في هذا الدرس سنسمّها ScalePage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي: <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="TransformsApp.ScalePage"> <StackLayout Padding="20, 10"> <Frame x:Name="frame" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" OutlineColor="Accent"> <Label Text="TEXT" FontSize="Large" /> </Frame> <Slider x:Name="scaleSlider" Minimum="-10" Maximum="10" Value="{Binding Source={x:Reference frame}, Path=Scale}" /> <Label Text="{Binding Source={x:Reference scaleSlider}, Path=Value, StringFormat='Scale = {0:F1}'}" HorizontalTextAlignment="Center" /> </StackLayout> </ContentPage> اذهب إلى بانية الصنف App الموجودة ضمن الملف App.cs واحرص على أن تكون على الشكل التالي: public App() { // The root page of your application MainPage = new ScalePage(); } نفّذ البرنامج لتحصل على شكل شبيه بما يلي: الخلاصة تحدثنا في هذا الدرس عن التحويلات الهندسية الأساسيّة: الانسحاب Translation والدوران Rotation والتحاكي Scale وكيفية التعامل معها من خلال Xamarin. في الحقيقة تكمن الحاجة لمثل هذه التحويلات غالبًا في تطبيقات الألعاب أو تلك التي تعتمد على الجانب الرسومي. سنعمل على تطبيق بعض من هذه التحويلات في الدروس القادمة من هذه السلسلة.
  3. تتكوّن تطبيقات الأجهزة المحمولة عادةً من صفحات منفصلة يتنقّل بينها المستخدم لاستفادة من الإمكانيات التي يقدمها التطبيق. بالنسبة لتطبيقات أندرويد فإنّ زر الرجوع إلى الخلف يُعتبر أساسيًا في عمليّة التنقّل هذه. سنتعرّف في هذا الدرس من سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms على كيفيّة التنقّل بين صفحات التطبيق. سنتحدّث أولًا عن مفهوم التنقّل بين الصفحات في التطبيق الواحد، ثمّ سنتحدّث عن أنواع صفحات المحتوى المستخدمة في التنقّل وذلك عن طريق مثال عملي بسيط. مفهوم التنقّل بين صفحات التطبيق يشبه التنقّل بين صفحات التطبيق مبدأ عمل المكدّس Stack إلى حدّ كبير. والمكدّس كما هو معلوم هو بنية معطيات تدعم مفهوم LIFO (الذي يدخل أخيرًا يخرج أولًا). فعند الانتقال من الصفحة A إلى الصفحة B، تُدفع pushed الصفحة B إلى أعلى المكدّس مما يؤدّي إلى ظهورها أمام المستخدم. وكذلك الأمر عند الانتقال من الصفحة B إلى الصفحة C يتم دفع الصفحة C إلى المكدّس ليتم إظهارها إلى المستخدم. أمّا عندما نريد العودة إلى الصفحة A الأصلية فيجب عندها أن تُخرج popped الصفحة C من المكدّس فتصبح الصفحة B أعلى المكدّس (أي تظهر للمستخدم) ثم تُخرج الصفحة B من المكدّس فتصبح الصفحة A أعلى المكدّس (أي تظهر للمستخدم). انظر الشكل التالي لتوضيح هذه الفكرة: صفحات Modal و Modeless يحتوي على كل تطبيق على صفحة رئيسيّة main page (ستكون من الصنف NavigationPage) تُعتبر العقدة الرئيسيّة التي يمكن الوصول من خلالها إلى جميع الصفحات الأخرى مهما كان عددها ومستواها. كما تميّز Xamarin بين نوعين من صفحات المحتوى التي تُستَخدم ضمن بنية التنقّل هذه وهي: الصفحات الجامدة Modal Pages والصفحات غير الجامدة Modeless Pages. الفرق بين هذين النوعين بالنسبة لتطبيقات أندرويد بسيط. وهو أنّه في الصفحات من النوع Modal لن يتم عرض عنوان الصفحة في الأعلى كما سنرى في المثال بعد قليل. أمّا في الصفحة من النوع Modeless فسيتم عنوان الصفحة في الأعلى في حال تمّ تحديده باستخدام الخاصيّة Title لصفحة المحتوى. لمعاينة الفرق بين هذه الأنواع لننشئ تطبيق عملي بسيط يوضّح هذا الأمر. ابدأ بإنشاء مشروع جديد من النوع Blank App (Xamarin.Forms Portable) وسمّه ModelessAndModal، ثم أبق فقط على المشروعين ModelessAndModal (Portable) و ModelessAndModal.Droid كما وسبق أن فعلنا في هذا الدرس. بعد ذلك سنضيف ثلاث صفحات محتوى عادية (Forms ContentPage) وهي: MainPage و ModalPage و ModelessPage. عدّل محتويات الملف MainPage ليكون مماثلًا لما يلي: 1 using Xamarin.Forms; 2 3 namespace ModelessAndModal 4 { 5 public class MainPage : ContentPage 6 { 7 public MainPage() 8 { 9 Title = "Main Page"; 10 11 Button gotoModelessButton = new Button 12 { 13 Text = "Go to Modeless Page", 14 HorizontalOptions = LayoutOptions.Center, 15 VerticalOptions = LayoutOptions.CenterAndExpand 16 }; 17 18 gotoModelessButton.Clicked += async (sender, args) => 19 { 20 await Navigation.PushAsync(new ModelessPage()); 21 }; 22 23 Button gotoModalButton = new Button 24 { 25 Text = "Go to Modal Page", 26 HorizontalOptions = LayoutOptions.Center, 27 VerticalOptions = LayoutOptions.CenterAndExpand 28 }; 29 30 gotoModalButton.Clicked += async (sender, args) => 31 { 32 await Navigation.PushModalAsync(new ModalPage()); 33 }; 34 35 Content = new StackLayout 36 { 37 Children = { gotoModelessButton, gotoModalButton } 38 }; 39 } 40 } 41 } ستعرض الصفحة الرئيسية MainPage زرّين فقط. الزر الأوًل هو gotoModelessButton ووظيفته إنشاء صفحة غير جامدة modeless والانتقال اليها. أمّا الزر الثاني فهو gotoModalButton ووظيفته إنشاء صفحة جامدة modal والانتقال إليها. بالنسبة للزر الأوّل gotoModelessButton انظر إلى الأسطر من 11 حتى 21: Button gotoModelessButton = new Button { Text = "Go to Modeless Page", HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.CenterAndExpand }; gotoModelessButton.Clicked += async (sender, args) => { await Navigation.PushAsync(new ModelessPage()); }; ننشئ في البداية كائنًا من النوع Button ونسنده إلى المتغيّر gotoModelessButton ثمّ نعيّن معالج لحدث النقر Clicked وهو عبارة عن تعبير lambda بسيط يمثّل تابع يحتاج إلى وسيطين sender و e وهو مسبوق بالكلمة المحجوزة async كما هو واضح من الشيفرة السابقة. سبب وجود الكلمة async هو أنّنا سنستخدم استدعاءً غير متزامنًا ضمن معالج الحدث هذا وهو: await Navigation.PushAsync(new ModelessPage()); يعمل التابع PushAsync المُستدعى من الخاصيّة Navigation للصفحة الحالية على دفع صفحة جديدة ضمن المكدّس الخاص بالتنقّل بين الصفحات، بمعنى آخر، سيعمل هذا التابع على إظهار صفحة جديدة من النمط modeless. في السطر السابق سيتم إنشاء صفحة جديدة من النوع ModelessPage ومن ثمّ تمريرها إلى التابع PushAsync. أنصحك بمراجعة هذا الدرس لكي تنعش ذاكرتك حول موضوع الاستدعاءات غير المتزامنة. نفس الأمر سيجري تمامًا بالنسبة للزر الخاص بالانتقال إلى الصفحة الجامدة مع فارق بسيط. وهو أنّ الاستدعاء هذه المرة سيكون من خلال التابع PushModalAsync (السطر 32) وذلك للانتقال إلى صفحة جامدة (ستكون من الصنف ModalPage). في كلّ من الحالتين السابقتين كان من الممكن أن نجعل معالجي حدثي النقر ضمن تابعين مستقلين وليس كما هو الحال من خلال تعبيري Lambda. الأمر الجدير بالملاحظة بالنسبة للصنف MainPage أيضًا هو تعيين الخاصيّة Title (السطر 9). في الحقيقة لم يكن لهذه الخاصيّة أي معنى في جميع البرامج التي أنشأناها في هذه السلسلة حتى الآن. إذ تعيين هذه الخاصيّة من عدمه لن يُحدث أيّ فرق! الجديد هنا هو في كيفيّة إنشاء الصفحة MainPage بحد ذاتها، والتي سننشئها كم جرت العادة ضمن الصنف App. انتقل إلى الملف App.cs واحرص على أن تكون بانيته مطابقة لما يلي: public App() { // The root page of your application MainPage = new NavigationPage(new MainPage()); } لاحظ معي الأمر الجديد هنا. نحن لا ننشئ صفحة محتوى ونسندها للخاصيّة MainPage مباشرةً كما كنّا نفعل من قبل. إنّما ننشئ صفحة محتوى (في مثالنا هي من الصنف MainPage) ثم نمرّر هذه الصفحة كوسيط إلى بانية الصنف NavigationPage. أي أنّنا في الواقع ننشئ صفحة محتوى تدعم التنقّل navigation. وهذا ما سيجعل عنوان الصفحة الرئيسيّة المُعيّن باستخدام الخاصيّة Title يظهر أعلى الصفحة كما سنرى بعد قليل. يمكننا الآن أن نجرّب هذا التطبيق. نفّذ التطبيق لتحصل على شكل شبيه بما يلي: أوقف تنفيذ البرنامج لنبدأ بالمرحلة الأخيرة وهي تجهيز صفحتي المحتوى ModalPage و ModelessPage. انتقل إلى الملف ModalPage.cs واحرص على أن تكون محتوياته مطابقة لما يلي: using Xamarin.Forms; namespace ModelessAndModal { public class ModalPage : ContentPage { public ModalPage() { Title = "Modal Page"; Button goBackButton = new Button { Text = "Back to Main", HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center }; goBackButton.Clicked += async (sender, args) => { await Navigation.PopModalAsync(); }; Content = goBackButton; } } } ثمّ انتقل إلى الملف ModelessPage.cs واحرص على أن تكون محتوياته كما يلي: using Xamarin.Forms; namespace ModelessAndModal { public class ModelessPage : ContentPage { public ModelessPage() { Title = "Modeless Page"; Button goBackButton = new Button { Text = "Back to Main", HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center }; goBackButton.Clicked += async (sender, args) => { await Navigation.PopAsync(); }; Content = goBackButton; } } } محتويات كلّ من الصفحتين السابقتين متطابقة. فكل منهما يحتوي على زر اسمه goBackButton هدفه العودة إلى الصفحة السابقة (التي سببت ظهور الصفحة الحالية). هناك فرق بسيط وحيد بين معالجي حدثي النقر للزرين في الصفحتين السابقتين. بالنسبة للصفحة من النمط الجامد modal تم استخدام الاستدعاء غير المتزامن Navigation.PopModalAsync للعودة إلى الصفحة السابقة. أمّا في حالة الصفحة ذات النمط غير الجامد modeless فقد تمّ استخدام الاستدعاء غير المتزامن Navigation.PopAsync للعودة إلى الصفحة السابقة. ثمة فرق آخر عند تنفيذ البرنامج، وهو أنّه في حالة الانتقال من الصفحة الرئيسية إلى الصفحة ModelessPage (الصفحة غير الجامدة) سيظهر عنوان الصفحة في الأعلى مع سهم صغير يسمح لنا بالعودة إلى الصفحة السابقة. أمّا عند الانتقال من الصفحة الرئيسية إلى الصفحة ModePage (الصفحة الجامدة) فلن يظهر عنوان الصفحة أبدًا (رغم تعيين الخاصيّة Title لها)، والوسيلة الوحيدة للرجوع إلى الصفحة السابقة هي بنقر زر الرجوع الموجود ضمن الصفحة أو بنقر زر العودة إلى الوراء الذي يزوّدنا به نظام التشغيل. أجرِ بعض التجارب على التطبيق ولاحظ الفرق بين الصفحتين. الخلاصة تناولنا في هذا الدرس آلية التنقّل بين الصفحات في تطبيقات أندرويد، وهو موضوع مهمّ بالطبع. حيث تعرّفنا إلى الفرق بين الصفحات من النمط modal والنمط modeless. كما تعلّمنا كيفية إنشاء الصفحة الرئيسيّة التي تُعتبر حجر البناء الأساسي في عمليّة الانتقال بين الصفحات، وذلك من خلال إنشاء الصفحة الرئيسيّة لتكون من النوع NavigationPage.
  4. سنتحدّث في هذا المقال من سلسلة المقالات حول التعامل مع ويندوز 10 عن المتصفّح الجديد Microsoft Edge، وهو موجود بشكل افتراضي ضمن ويندوز 10. عملت مايكروسوفت على بناء هذا المتصفّح من الصفر وذلك كبديل للمتصفّح الشهير (سيّء الصيت) Internet Explorer. وضعت مايكروسوفت إمكانيات كبيرة للخروج بمتصفّح Edge بهذه الصورة، وذلك للدخول في سباق المتصفّحات المحموم للفوز ولو بحصّة معقولة من هذا السوق. دمجت مايكروسوفت بعض وظائف المساعد الشخصي Cortana مع Edge ولكنّنا لن نتكلّم في هذه السلسلة مع الأسف عن Cortana وذلك لأنّه غير مدعوم حتى هذه اللحظة مع النسخة العربية لويندوز 10. سنتناول في هذا المقال بعض مزايا هذا المتصفّح الجديد والتي وجدتها مثيرة للاهتمام. وضع ملاحظات مباشرةً على صفحة ويب وهي ميزة مهمة وجميلة في Edge حيث يمكن وضع ملاحظات مباشرةً ضمن أيّ صفحة ويب نرغب بها وذلك على أيّ مكان في الصفحة. افتح متصفّح Edge لديك وانتقل إلى الموقع http://academy.hsoub.com لتظهر الصفحة الرئيسية كما في الشكل التالي. لاحظ الأيقونة المحاطة بإطار أحمر والموجودة في الأعلى. انقر على هذه الأيقونة ليظهر شريط أدوات الملاحظات في الأعلى. كما في الشكل التالي. بالنسبةإلي، اخترت أداة القلم وقمت برسم شكل مغلق حول جزء أعجبني من الصفحة، كما اخترت أداة التعليقات ووضعت تعليقًا أيضًا على هذه الصفحة كما في الشكل التالي. بعد أن نفرغ من تدوين الملاحظات يمكن نقر أيقونة الحفظ الموجودة في الجهة اليسرى، أو نقر أيقونة المشاركة الموجودة بجوارها. المثير في الأمر أنّه في حال نقرت أيقونة الحفظ سيخيرك متصفّح Edge بطريقة حفظ هذه الملاحظات. حيث سيظهر ضمن إحدى هذه الخيارات استخدام تطبيق OneNote لتدوين الملاحظات والذي تحدثنا عنه في المقال السابق وذلك لمزامنة أيّ ملاحظات ستسجّلها على هذه الصفحة، وبالتالي يمكنك الوصول إلى هذه الملاحظات في أي وقت ومن خلال أي جهاز ترغبه. اختر OneNote لحفظ الملاحظات ثم انقر زر "حفظ" سيخبرك Edge أنّ ملاحظاتك قد تمّ حفظها ضمن تطبيق OneNote وبالتالي أصبح من الممكن الوصول إليها من أيّ مكان. يمكنك التأكّد من ذلك بفتح تطبيق OneNote ومشاهدة الملاحظات التي تمّ تدوينها على الصفحة الرئيسية للموقع. إنشاء قائمة قراءة بسيطة تُعتبر ميزة "قائمة القراءة" الموجودة في متصفّح Edge من المزايا المفيدة التي يحتاجها الكثير من المستخدمين. حيث يمكننا إنشاء قائمة خاصّة للصفحات التي نودّ مراجعتها بترتيب منطقي متسلسل. يمكن وضع أي صفحة ويب ضمن قائمة القراءة بالنقر على أيقونة المفضّلة (رمز النجمة) الموجودة بجوار شريط العنون، ثم اختر أن تُوضع هذه الصفحة ضمن قائمة القراءة وليس ضمن المفضّلة. يمكن بعد ذلك الوصول لقائمة القراءة بالنقر على أيقونة "الموزّع" وهي على شكل ثلاثة خطوط أفقيّة متوازية، ثم النقر على أيقونة قائمة القراءة كما يظهر من الشكل التالي: يمكنك ملاحظة أنّني قد أضفت عدّة صفحات لمراجعتها ضمن الترتيب الزمني الذي أضفتها فيه. توجد بالطبع العديد من الإضافات الخارجيّة التي توفّر لنا هذه الميزة وربما بطريقة احترافية أكثر. ولكن في حال أردنا فقط وسيلة بسيطة لتنظيم ما نودّ قراءته لاحقًا فلا حاجة للجوء لمثل هذه الإضافات والاكتفاء بما يوفّره Edge. مشاركة المحتوى أثناء التصفّح يمتلك متصفّح Edge أسلوب سهل لمشاركة المحتوى مع الآخرين فيمكنك النقر على أيقونة "المشاركة" (ثلاث دوائر صغيرة تقع على محيط دائرة أكبر). عند النقر على هذه الأيقونة سيعرض لك متصفّح Edge قائمة بالتطبيقات التي تسمح بالمشاركة والتي قمت بتفعيلها عن طريقه، أو تلك التي مفعّلة بشكل تلقائي من قِبَل Edge. يمكنك زيادة عدد هذه التطبيقات من خلال تنصيب المزيد منها عن طريق متجر ويندوز Windows Store. قد يختلف لون أرضية القائمة التي تظهر في الشكل السابق عن تلك التي تظهر عندك وذلك بسبب اختلاف إعدادات الألوان الافتراضيّة المعتمدة لديك. تثبيت صفحات الويب ضمن قائمة البداية من الممكن في حال وجدت أنّ صفحة ويب ما أنّها مهمة أو أنّك تزورها باستمرار، أن تثبّتها ضمن قائمة البداية. فقط عليك زيارة صفحة ويب المطلوبة ثم تنقر زر "المزيد" من الأعلى (ثلاث نقاط متجاورة أفقيًّا) انقر خيار "تثبيت هذه الصفحة بشاشة البدء" بعد نقرك على هذا الخيار، يمكنك الانتقال فورًا إلى شاشة البدء لتلاحظ ظهور لوح tile جديد يسمح لك بالوصول السريع لصفحة الويب هذه. انظر الشكل التالي: المزايا الأمنية تم بناء متصفّح Edge مع الأخذ بعين الاعتبار الثغرات الكبيرة التي كانت تعتري المتصفّح القديم Internet Explorer (الذي ما يزال موجودًا بشكل افتراضي في نظام التشغيل). أصبح Edge يمنع استخدام عناصر ActiveX أو النصوص البرمجيّة المكتوبة بلغة VBScript والتي كان من الممكن استخدامها للقيام بالعديد من الخروقات الأمنيّة التي تصيب جهاز المستخدم. أصبح متصفّح Edge يعتمد فقط على HTML5 بالإضافة إلى النصوص البرمجيّة المكتوبة بلغة JavaScript. وبالتالي فإنّ أي موقع لا يزال يستخدم تقنيات قديمة مثل ActiveX لن يتمّ عرضه بصورة صحيحة في Edge. توجد في الحقيقة العديد من المزايا الأمنية الأخرى التي يتمتّع بها Edge مثل التشغيل في وضع العزل Sandboxing. وهي ميزة مهمّة تسمح بتشغيل الجزء البرمجي الذي يعرض الصفحة ويعالج محتواها ضمن حاوية برمجيّة عازلة، مما يمنع أي شيفرة برمجيّة ضارة من الاستفادة من موارد الحاسوب الذي تعمل عليه. يتمتّع Edge أيضًا بنوع من الذكاء الاصطناعي في توقّع الأخطاء قبل حدوثها. حيث اعتمدت مايكروسوفت على المنطق الضبابي Fuzzy Logic في توقّع الأخطاء والمشاكل المحتملة قبل حدوثها وذلك بالاستناد إلى تجارب سابقة تتخطى 400 مليون تجربة في تحليل ومعالجة صفحات HTML، مما يجعل Edge أكثر قدرة على تفادي المشاكل قبل وقوعها قدر الإمكان. الخلاصة تعرّفنا في هذا المقال على بعض المزايا الجديدة والمفيدة التي يتمتّع بها متصفّح الويب Edge. ذلك المتصفّح المجّاني والجديد من مايكروسوفت. لقد رأينا كيف نستطيع وضع ملاحظات مباشرة على صفحة الويب، ومن ثمّ حفظها ومشاركتها بأساليب مختلفة. كما تعلّمنا كيفيّة بناء قائمة للقراءة، وكيف نثبّت صفحة ويب مهمّة كلوح ضمن قائمة البداية. وتعرّفنا في النهاية على المزايا الأمنيّة الجديدة التي يدعمها Edge.
  5. سنتعرّف في هذا الدرس من ضمن سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms على تقنيّة متقدّمة بعض الشيء، وهي البرمجة غير المتزامنة Asynchronous Programming. وهي تقنيّة مهمّة تسمح للمبرمجين ببناء تطبيقات مرنة وذات استجابة عالية عند الاستخدام. سيتناول هذا الدرس الحاجة إلى البرمجة غير المتزامنة، ويقدّم تطبيق عملي بسيط يعمل على توضيح فكرة البرمجة غير المتزامنة من خلال تطبيق بسيط للغاية. الحاجة إلى البرمجة غير المتزامنة تسلك التطبيقات نفس السلوك في معالجة مُدخلات المستخدم التي قد تكون عبارة عن نقرة فأرة أو لمسة على الشاشة أو ضغط على مفتاح من لوحة المفاتيح. إذ يجب أن تُعالج هذه المدخلات بشكل متسلسل حسب ترتيب وقوعها. ولا يتم الانتقال من مُدخل إلى مُدخل آخر إلّا بعد الانتهاء من معالجة التعليمات البرمجيّة التي سبّبها المُدخل الحالي. فإذا فرضنا مثلًا وجود زرّين على الشاشة، فإذا نقرت (لمست) الزرّين بشكل متتال وبسرعة، فإنّ التعليمات الموجودة في معالج حدث النقر للزر الذي لُمسَ أولًا سيتم تنفيذها بالكامل، وبعد ذلك ينتقل البرنامج لتنفيذ مجموعة التعليمات البرمجيّة الموجودة في معالج حدث النقر للزر الثاني. بمعنى آخر، لن يتم تنفيذ التعليمات البرمجيّة للزرّين معًا، حتى وإن بدا للمستخدم أنّه قد نقرهما (لمسهما) معًا. وهذا أمر طبيعي تمامًا ويجري في جميع التطبيقات التي تعمل على أنظمة التشغيل المختلفة. السبب في هذا الأمر، هو أنّه وبشكل افتراضي يعمل التطبيق ضمن ما يُسمّى بمسار تنفيذ Thread رئيسي. يضمن مسار التنفيذ هذا أن يتم التنفيذ بالصورة التي أوضحناها قبل قليل. وفي الحقيقة يُسمّى مسار التنفيذ الرئيسي أحيانًا بمسار التنفيذ الخاص بواجهة المستخدم UI Thread وذلك لأنّ جميع العناصر المرئيّة يتم التعامل معها حصرًا من خلاله. تكمن المشكلة في أنّ بعض التطبيقات قد تحتاج إلى زمن طويل نسبيًا في تنفيذ التعليمات البرمجيّة الموجودة -ولنقل- في أحد معالجات الأحداث. فقد ينقر (يلمس) المستخدم زرًا يؤدّي مثلًا إلى جلب بعض البيانات من الإنترنت، وهي عمليّة قد تتطلّب في بعض الأحيان زمنًا طويلًا نسبيًّا وذلك لأسباب متنوّعة لسنا بمعرض الحديث عنها حاليًّا. سيعني هذا بكلّ تأكيد أنّ واجهة التطبيق ستبقى جامدة ولا تستجيب حتى تنجح عملية جلب البيانات أو تفشل لسبب ما. السيناريو السابق غير مرغوب بكل تأكيد، فلا بدّ من وجود طريقة ما تسمح بجلب البيانات دون التأثير على واجهة التطبيق الأساسيّة، أو بمعنى أدق، دون التأثير على مسار التنفيذ الرئيسي UI Thread. تُوفّر العديد من لغات البرمجة تقنيّة مهمّة لحل هذه المشكلة تتمثّل في استخدام مسارات تنفيذ أخرى (نسميها مسارات التنفيذ العاملة Worker Threads) يتم من خلالها تنفيذ المهام المتنوّعة التي يتطلّبها التطبيق والتي قد تستغرق زمنًا طويلًا نسبيًّا وذلك دون التأثير على مسار التنفيذ الرئيسي UI Thread. تُسمّى هذه التقنيّة بالبرمجة ذات مسارات التنفيذ المتعدّدة Multi-Threading Programming وهي من التقنيّات البرمجيّة المتقدّمة، وليس من السهل العمل معها. توفّر معظم لغات البرمجة بما فيها سي شارب حلول مبسّطة تُعفي المستخدم من مغبّة التورّط -إن صحّ التعبير- في موضوع متقدّم كهذا. الحل الذي تقدّمه سي شارب هو في البرمجة غير المتزامنة Asynchronous Programming حيث تعمل هذه التقنيّة على تنفيذ المهام البرمجيّة التي تتطلّب وقتًا طويلًا نسبيًّا ضمن ما يشبه مسارات تنفيذ منفصلة عن مسار التنفيذ الرئيسي، بحيث يمكن القول أنّ التعليمات البرمجيّة الموجودة ضمن معالجات أحداث مختلفة يصبح من الممكن تنفيذها بشكل متوازٍ بدلًا من الشكل المتسلسل الذي تحدثنا عنه. انظر إلى الشكل التالي الذي يوضّح الفرق العام بين التطبيقات التي تستخدم مسار التنفيذ الرئيسي فقط، وبين التطبيقات التي تستخدم مسارات تنفيذ متعدّدة. تطبيق العدّاد المحسّن مع استدعاء غير متزامن تذكر معي تطبيق العدّاد المحسّن الذي تناولناه في هذا الدرس. سنجري تعديلًا عليه بحيث سنعمل على إضافة زر جديد لإجراء استدعاء غير متزامن يعمل على محاكاة عمليّة برمجيّة تستغرق 5 ثانية، بالإضافة إلى لصيقة تقع أسفل الزر السابق لعرض رسالة بعد الانتهاء من عمليّة الاستدعاء غير المتزامن. أثناء تنفيذ هذه العمليّة البرمجيّة سنضغط على زرّي الزيادة والإنقاص، وسيتابع التطبيق العمل بشكل طبيعي دون حدوث أيّ جمود على واجهة المستخدم. بعد انقضاء العمليّة الناتجة عن الاستدعاء غير المتزامن بعد 5 ثانية، سيعرض التطبيق رسالة "Hello From Async." ضمن لصيقة تقع أسفل الزر للإشارة إلى انتهاء هذه العمليّة. انظر الشكل التالي لمعاينة الشكل الجديد لذلك التطبيق: أنشئ مشروعًا جديدًا من النوع Blank App (Xamarin.Forms Portable) وسمّه AsyncCounterApp، ثم أبق فقط على المشروعين AsyncCounterApp (Portable) و AsyncCounterApp.Droid كما وسبق أن فعلنا في هذا الدرس. بعد ذلك أضف صفحة محتوى وسمّها AsyncEnhancedCounterPage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي: 1 using System; 2 using System.Threading.Tasks; 3 using Xamarin.Forms; 4 5 namespace AsyncCounterApp 6 { 7 public class AsyncEnhancedCounterPage : ContentPage 8 { 9 Label lblDisplayAsync; 10 11 public AsyncEnhancedCounterPage() 12 { 13 int counter = 0; 14 15 Label lblDisplay = new Label 16 { 17 Text = "0", 18 TextColor = Color.Accent, 19 HorizontalOptions = LayoutOptions.CenterAndExpand, 20 FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)) 21 }; 22 23 Button btnIncrement = new Button 24 { 25 Text = "+", 26 HorizontalOptions = LayoutOptions.CenterAndExpand, 27 FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)) 28 }; 29 btnIncrement.Clicked += (s, e) => 30 { 31 counter++; 32 lblDisplay.Text = counter.ToString(); 33 }; 34 35 Button btnDecrement = new Button 36 { 37 Text = "-", 38 HorizontalOptions = LayoutOptions.CenterAndExpand, 39 FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)) 40 }; 41 btnDecrement.Clicked += (s, e) => 42 { 43 if (counter == 0) 44 { 45 DisplayAlert("تحذير", "لا يمكن لقيمة العدّاد أن تكون أصغر من الصفر", "موافق"); 46 } 47 else 48 { 49 counter--; 50 lblDisplay.Text = counter.ToString(); 51 } 52 }; 53 54 Button btnAsyncCall = new Button 55 { 56 Text = "Async Call", 57 HorizontalOptions = LayoutOptions.CenterAndExpand, 58 FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)) 59 }; 60 btnAsyncCall.Clicked += BtnAsyncCall_Clicked; ; 61 62 lblDisplayAsync = new Label 63 { 64 TextColor = Color.Green, 65 HorizontalOptions = LayoutOptions.CenterAndExpand, 66 FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)) 67 }; 68 69 Content = new StackLayout 70 { 71 Children = { 72 new StackLayout 73 { 74 Orientation = StackOrientation.Horizontal, 75 Padding = new Thickness(0,64,0,64), 76 Children = 77 { 78 btnIncrement, 79 btnDecrement 80 } 81 }, 82 lblDisplay, 83 btnAsyncCall, 84 lblDisplayAsync 85 } 86 }; 87 } 88 89 private async void BtnAsyncCall_Clicked(object sender, EventArgs e) 90 { 91 //simulate long process execution for 5 seconds 92 string msg = await Task<string>.Run(() => 93 { 94 DateTime d = DateTime.Now; 95 96 while (DateTime.Now.Second - d.Second < 5) ; 97 98 return "Hello from Async."; 99 }); 100 101 lblDisplayAsync.Text = msg; 102 } 103 } 104 } لقد تناولنا الشيفرة السابقة من قبل. لذلك سنتحدّث عن عمليّة الاستدعاء غير المتزامن فحسب. لقد أسندنا لحدث نقر الزر btnAsyncCall معالج حدث BtnAsyncCall_Clicked وهو موجود في الأسطر من 89 حتى 102. الجديد في معالج الحدث هذا هو وجود الكلمة المحجوزة async (السطر 89) قبل نوع القيمة المعادة مباشرةً. تُشير هذه الكلمة المحجوزة إلى أنّ عملية الاستدعاء غير المتزامن ستجري ضمن التابع BtnAsyncCall_Clicked. انظر الآن إلى الأسطر من 92 إلى 99: string msg = await Task<string>.Run(() => { DateTime d = DateTime.Now; while (DateTime.Now.Second - d.Second < 5) ; return "Hello from Async."; }); لاحظ التابع الساكن Run من الصنف العمومي Task<string>. يعمل هذا التابع على استدعاء أيّ تابع مُمرّر إليه ضمن مسار تنفيذ منفصل عن مسار التنفيذ الأساسي، وبالتالي لا يُشغل مسار التنفيذ الأساسي المرتبط بواجهة المستخدم. يجب أن يُسبق الاستدعاء غير المتزامن بالكلمة المحجوزة await. لقد مرّرنا إلى التابع Run تعبير Lambda يحتوي التعليمات البرمجيّة التي نريد تنفيذها على مسار تنفيذ مستقل (للمزيد حول تعابير Lambda انظر هنا). من الواضح أنّنا قد كتبنا شيفرة برمجيّة لا تقوم بعمل مفيد بكل تأكيد، إنما الغاية الوحيدة منها هي توضيح فكرة الاستدعاء غير المتزامن، حيث أجريت تأخيرًا زمنيًّا باستخدام حلقة while يستغرق 5 ثواني. سنكتفي بهذه المقدّمة حول البرمجة غير المتزامنة، مع التأكيد على أنّنا سنتوسّع في هذا الموضوع حينما نتناول تطبيقًا عمليًّا مفيدًا لاحقًا في هذه السلسلة. الخلاصة تحدثنا في هذا الدرس عن مفهوم البرمجة غير المتزامنة Asynchronous Programming والحاجة إليها في التطبيقات التي نصمّمها لضمان أنّ العمليات البرمجيّة التي قد تستغرق وقتًا طويلًا نسبيًّا لن تؤدّي إلى جمود في واجهة المستخدم. ثمّ أجرينا تعديلًا بسيطًا على تطبيق بنيناه في درس سابق بحيث نجري استدعاءً غير متزامنًا يستغرق وقتًا لا بأس به حتى ينتهي، ورغم ذلك استطاع المستخدم متابعة العمل على التطبيق دون أيّ تأثير على واجهة التطبيق. لن نكتفي بكلّ تأكيد بما وصلنا إليه هنا، سنتوسّع بالحديث عن هذا الموضوع المهم لاحقًا حينما نبدأ بتنفيذ تطبيقات عمليّة باستخدام Xamarin.
  6. نتابع رحلتنا في سلسلة المقالات حول التعامل مع ويندوز 10 مع هذا الدرس الذي يتحدّث عن بدء العمل مع ويندوز 10 من خلال التعرّف على بعض المزايا الأساسيّة البسيطة التي تسهّل المهام اليوميّة. أصبح ويندوز 10 أكثر قابليّة وسهولة للتخصيص، سنتحدّث عن كيفيّة تخصيص الألواح Tiles في شاشة البدء، بالإضافة إلى كيفيّة تثبيت أيقونات التطبيقات على شريط المهام. كما سنتعرّف على منطقة الإشعارات، والفائدة التي يمكن أن نجنيها منها. الألواح Tiles اللوح Tile هو من المزايا الجديدة التي بدأت بالظهور منذ ويندوز 8 وقد شهدت تحسينًا في ويندوز 10. تتوضّع الألواح ضمن شاشة البدء على شكل مربّعات صغيرة قد تحتوي على محتوى متحرّك، وتعرض معلومات مفيدة للمستخدم. تتنوّع هذه المعلومات من حالة الطقس، آخر الأخبار المتوفرة حاليًّا، أسعار العملات، إلى آخر رسائل البريد الإلكتروني، وغيرها من المعلومات المختصرة والمفيدة بنفس الوقت. يمكنك إضافة لوح جديد إلى شاشة البدء عن طريق خطوتين بسيطتين. انتقل أولًا إلى شاشة البدء عن طريق نقر زر ابدأ، ثم اختر التطبيق الذي ترغب بتثبيته كلوح ضمن شاشة البدء. لاحظ أنّ التطبيقات مصنّفة ضمن مجموعات مرتّبة أبجديًّا. يمكنك أن تنتقي التطبيق الذي تريده بسهولة من هذه القائمة، أو حتى يمكنك الوصول إليه مباشرةً عن طريق كتابة اسمه على لوحة المفاتيح، وسيقوم ويندوز 10 بالبحث عن التطبيق أثناء الكتابة حيث يعرض عليك نتائج البحث على شكل قائمة تختار منها التطبيق المناسب. بصرف النظر عن الأسلوب الذي استخدمته للوصول إلى تطبيقك، انقر على أيقونة التطبيق المطلوب بزر الفأرة الأيمن لكي تظهر قائمة منبثقة، اختر منها البند "تثبيت بشاشة البدء". كما يظهر من الشكل التالي فقد اخترت تطبيق الرسام الذي يأتي ضمن التطبيقات الملحقة بويندوز. ستلاحظ ظهور أيقونة تطبيق الرسام ضمن شاشة البدء مباشرةً. إذا أمعنت النظر في شاشة البدء بعد إضافة تطبيق الرسام كلوح إليها، ستجد أنّ اللوح الذي يمثّل هذا التطبيق سيظهر كما لو أنّه متطرّف قليلًا عن باقي الألواح. يعود السبب في ذلك إلى أنّ ويندوز يعمل على إضافة هذا اللوح ضمن مجموعة منفصلة. إذ أنّ الألواح تُصنّف في الواقع ضمن مجموعات لكي يتمكّن المستخدم من تنظيم تطبيقاته ضمن مجموعات منطقيّة تجعل عمليّة الوصول إليها سهلة نسبيًّا. حرّك مؤشّر الفأرة أعلى لوح تطبيق الرسام مباشرةً، ستلاحظ ظهور النص "تسمية المجموعة" وهو نص قابل للتعديل يمثّل عنوان هذه المجموعة من الألواح. إذا نقرت على هذا النص يمكنك إدخال الاسم الذي يناسبك، كما يمكنك إضافة أي عدد من الألواح لهذه المجموعة بنفس الأسلوب السابق. يمكنك أيضًا نقل لوح من مجموعة إلى أخرى، وذلك بالضغط بزر الفأرة الأيسر عليه وسحبه ومن ثمّ إفلاته ضمن المجموعة المطلوبة. كما يمكنك أيضًا إزالة لوح من شاشة البدء وذلك بأن تنقر عليه بزر الفأرة الأيمن، ثمّ تختار "إزالة التثبيت من شاشة البدء". شريط المهام Task Bar هو الشريط الذي يمتد على كامل عرض الشاشة من الأسفل، ويبدأ بزر ابدأ وينتهي بمنطقة الإشعارات من الجهة اليسرى. أي نافذة أو برنامج يتم فتحها في ويندوز 10 ستُوضع لها أيقونة في هذا الشريط، أمّا عند إغلاق هذه النافذة أو التطبيق تختفي هذه الأيقونة. قد نرغب أحيانًا بتثبيت أيقونات بعض التطبيقات بشكل دائم بهدف الوصول السريع لها. يمكن ذلك من خلال اختيار التطبيق المطلوب من شاشة البدء (كما فعلنا في الفقرة السابقة) والنقر بزر الفأرة الأيمن عليه. نختار البند "تثبيت إلى شريط المهام" ليعمل ويندوز إلى تثبيت اختصار مباشر لهذا التطبيق ضمن شريط المهام. منطقة الإشعارات يمكن الوصول إلى هذه المنطقة من خلال النقر على الأيقونة الصغيرة التي تظهر بجوار الساعة. توجد العديد من المميزات المفيدة في هذه المنطقة. في البداية يمكنك الاطلاع على رسائل البريد الإلكتروني الجديدة (على فرض أنّك قد ربطت حساب مايكروسوفت بنسخة ويندوز 10 التي لديك كما فعلنا في الدرس السابق). كما يمكنك الوصول إلى إعدادات الحاسوب لديك، وإلى مركز الصيانة الذي سنتحدّث عنه لاحقًا، ويمكنك أيضًا إجراء عمليات ضبط سريعة للحاسوب لديك كما يظهر من الشكل التالي: توجد العديد من الاختصارات السريعة كما يظهر من الشكل السابق والتي سنتحدّث عن كلّ منها بشكل مختصر: يفيد الزر "وضع الكومبيوتر اللوحي" في جعل حاسوبك يتصرّف كما لو أنّه جهاز لوحي. وهذه ميزّة مهمّة إذا كان حاسوبك هو لوحيّ فعلًا (كما في سلسلة Surface مثلًا). أمّا زر "تأمين التدوير" فهو مفيد أيضًا في حال كان حاسوبك لوحيًّا. اختصار "مفكرة" يؤدّي إلى تشغيل تطبيق "OneNote" وهو تطبيق ملحق بمجموعة Office، ولكنّه مضمّن في ويندوز 10 بشكل افتراضي، وهو يسمح للمستخدم بتدوين ملاحظات احترافية يمكنك مزامنتها عبر الانترنت (في حال كانت نسخة ويندوز لديك مرتبطة بحساب مايكروسوفت). يفيد زر "كل الإعدادات" في الوصول إلى لوحة إعدادات الحاسوب. يؤدّي تفعيل زر "الموقع" إلى السماح للتطبيقات بمعرفة الموقع الذي يعمل منه الحاسوب. يمكنك النقر على هذا الزر لتفعيل هذه الميزة أو إلغاء تفعيلها. يؤدّي الضغط على زر "ساعات الهدوء" إلى تفعيل هذه الميزة، والتي تتمثّل في منع الحاسوب من إصدار أي تنبيه أو إشعار بين منتصف الليل والساعة السادسة صباحًا. على فرض أنّ الحاسوب في وضع تشغيل خلال هذه الساعات. ويمكنك بالطبع الضغط على هذا الزر مرّة أخرى لإلغاء هذه الميزة. زر VPN ينقلك إلى الإعدادات الخاصة بالشبكات الظاهرية الخاصة Virtual Private Networks التي يستخدمها الحاسوب. زر "عرض"، وهو مفيد عندما نستخدم جهاز إسقاط ضوئي Projector، حيث يمكن التحكم بمجموعة من خيارات العرض المختلفة، كالتحكّم فيما إذا كان العرض على شاشة الحاسوب فقط، أو على شاشة جهاز الإسقاط الضوئي فقط، أو على سطح مكتب ممتد عبر الشاشة وجهاز الإسقاط، أو عرض مكرّر على الشاشة وجهاز الإسقاط. يسمح زر "اتصال" بالاتصال لاسلكيًّا بالأجهزة التي تتمتّع بميزة Miracast (بما فيها حاسوبك الشخصي). زر "الشبكة" يسمح بعرض حالة الشبكة الحالية، والانتقال إلى إعدادات الشبكات. الخلاصة هناك الكثير مما يمكننا التحدّث عنه حول ويندوز 10. هذا النظام الذي يُعتبر قفزة نوعيّة في أنظمة التشغيل التي تنتجها مايكروسوفت. لقد بدأنا في هذا الدرس بمعرفة كيفيّة التعامل مع المزايا الأساسيّة التي ستصادفها مرارًا أثناء استخدامك اليومي لويندوز. حيث تعرّفنا على ماهية الألواح Tiles وكيفيّة استخدامها، وكيفيّة تثبيت اختصارات للتطبيقات التي كثيرًا ما تحتاجها ضمن شريط المهام. كما تعرّفنا على منطقة الإشعارات التي تحتوي على الكثير من الميزات التي قد يحتاجها المستخدم في عمله في ويندوز 10.
  7. بعد أن انتهينا من تنصيب ويندوز 10 في الدرس السابق سنعمل في هذا الدرس من سلسلة المقالات حول التعامل مع ويندوز 10 على تنفيذ بعض الإجراءات الضروريّة قبل البدء باستخدام ويندوز 10. تشتمل هذه الإجراءات على القيام بتحديثين ضروريين، وهما التحديث الخاص ببرنامج الحماية المرفق مع ويندوز وهو Windows Defender بالإضافة إلى التحديث الخاص بنظام التشغيل نفسه. كما سنعمل على ربط نسخة ويندوز 10 بحساب حساب مايكروسوفت Microsoft Account للاستفادة القصوى من المزايا التي يوفّرها نظام التشغيل ويندوز 10. إجراء التحديثات اللازمة قد تستغرب في البداية أنّني لست مقتنعًا بنظام الحماية Windows Defender المضمّن بشكل مجانيّ مع ويندوز 10. أمّا سبب شرحي حول كيفيّة تحديثه لضمان أمن الحاسوب، فالجواب ببساطة لأنّه مجّانيّ وموجود سلفًا في ويندوز، وبالتالي يُعتبر كأحد مزايا نظام التشغيل. برأيي الشخصي هناك بدائل أخرى أفضل من Windows Defender وهي مجانيّة أيضًا مثل تطبيق Avira الذي أنصحك بالاطلاع عليه. أمّا في حال كنت مستعدًّا لدفع بعض الدولارات فيمكنك استخدام Norton Symantec أو Kaspersky. لإجراء التحديث الخاص بنظام الحماية Windows Defender انقر زر ابدأ لتظهر قائمة البداية. ثم انقر بعد ذلك زر الإعدادات الصغير الموجود في الجهة اليمنى من الأسفل، كما يظهر في الشكل التالي: ستظهر نافذة الإعدادات بشكلها الجديد. اختر من هذه النافذة بند "التحديث والأمان" كما في الشكل التالي: ربما ستحتاج إلى استخدام شريط التمرير ان لم يكن هذا البند ظاهرًا. بعد ظهور الصفحة الخاصة بالتحديث والأمان، اختر من القائمة التي تظهر في الجهة اليمنى العنصر Windows Defender لتظهر الصفحة الخاصة بـ Windows Defender كما في الشكل التالي: انقر الزر "فتح Windows Defender" كما يظهر من الشكل السابق، ليعمل ويندوز على فتح نافذة هذا التطبيق. سيعرض التطبيق رسالة ترحيبيّة توضّح مزايا Windows Defender. انقر الزر إغلاق للوصول إلى النافذة الرئيسيّة للتطبيق. انقر اللسان "تحديث" الذي ستجده في الأعلى للانتقال إلى القسم الخاص بتحديث التعريفات الخاصة بالفيروسات. بعد ذلك، انقر زر "تحديث التعريفات" لتبدأ هذه العمليّة التي قد تأخذ بعض الوقت حسب سرعة الاتصال التي لديك. بعد الانتهاء من تحديث تعريفات الفيروسات أغلق نافذة تطبيق Windows Defender. سيظل التطبيق يعمل في الخلفيّة ليؤمّن الحماية المطلوبة. حان الوقت الآن لتحديث نظام التشغيل، وهو أمر مهمّ جدًّا بالنسبة لويندوز 10. فهناك العديد من التحديثات التي تجري تباعًا، سواءً لإضافة مزايا جديدة، أو لتلافي ثغرات أمنيّة أو مشاكل تقنيّة. من نفس صفحة "التحديث والأمان" اختر من القائمة التي تظهر في الجهة اليمنى البند "Windows Update" لتظهر الصفحة الخاصة بتحديثات ويندوز. انقر زر "التحقّق من وجود تحديثات" كما في الشكل التالي: قد يستغرق الأمر بعضًا من الوقت بحسب سرعة الاتصال لديك، بالإضافة إلى الوقت اللازم لتطبيق هذه التحديثات على نظام التشغيل. قد تبدو العمليّة مملّة لأنّها قد ستستغرق وقتًا طويلًا للمرّة الأولى، وقد تتضمّن إعادة تشغيل الحاسوب. الربط مع حساب مايكروسوفت من الممكن ربط نسخة ويندوز 10 التي لدينا بحساب مايكروسوفت التابع لك. وحساب مايكروسوفت قد يكون عبارة عن حساب بريد إلكتروني عادي تمتلكه على بريد هوتميل Hotmail مثلًا. إذا لم تكن تمتلك مثل هذا الحساب، انتقل إلى صفحة هوتميل www.hotmail.com لتظهر لك صفحة خاصّة بتسجيل الدخول كما في الشكل التالي: انقر الرابط Create one الموجود أسفل الزر Next كما هو واضح من الشكل السابق. سينتقل بك المتصفّح إلى الصفحة الخاصة بإنشاء حساب مايكروسوفت جديد. أدخل البيانات الخاصّة بك، ثم تابع التسجيل حتى تحصل على حساب جديد. انقر الآن زر ابدأ، ثم انتقل إلى الإعدادات كما فعلنا من قبل. من الصفحة الرئيسية للإعدادات انقر "الحسابات": اختر من صفحة "الحسابات" البند "البريد الإلكتروني وحسابات التطبيق" من القائمة الموجودة في الجهة اليمنى لتظهر الصفحة الموافقة كما يلي: بعد أن تظهر هذه الصفحة، انقر الزر + الصغير الذي يظهر في وسط الصفحة بجوار عبارة إضافة حساب كما في الشكل السابق. سيؤدي ذلك إلى فتح نافذة صغيرة تخيّرك بين أنواع متعدّدة للحسابات التي يقبل ويندوز 10 أن يضمّها. سنختار من هذه النافذة البند الخاص بحسابات مايكروسوفت وهو Outlook.com كما في الشكل التالي: وهو يتضمّن طيفًا واسعًا من حسابات البريد الإلكتروني التابعة لمايكروسوفت. بعد أن تختار هذا البند سيطلب منك ويندوز 10 تزويده بمعلومات هذا الحساب. أدخل البريد الإلكتروني وكلمة المرور في المربّعين المناسبين ثم انقر زر "تسجيل الدخول". سيعرض ويندوز 10 لك نافذة توضّح الإجراءات التي سيقوم ويندوز 10 بتطبيقها عند ربط نسخة ويندوز التي لديك بحساب مايكروسوفت. كما سيطلب التحقّق من شخصيتك بأن تكتب كلمة المرور الحالية لنسخة ويندوز. إذا لم تُعيّن أي كلمة مرور سابقة لنسخة ويندوز، يمكنك ترك هذا الحقل فارغًا. انقر زر التالي ليبدأ ويندوز 10 عملية الربط التي قد تأخذ القليل من الوقت. بعد أن تنتهي عمليّة الربط يجب أن تحصل على رسالة تخبرك بأنّ العمليّة تمّت بنجاح، ثمّ سيتم إضافة الحساب الخاص بك إلى قائمة الحسابات المعتمدة. يمكنك الآن إغلاق نافذة الإعدادات. الفائدة المباشرة لموضوع الربط هذا، هو أنّ بريدك الإلكتروني سيتم ربطه بشكل تلقائي مع برنامج البريد الافتراضي في ويندوز 10، وإذا كنت قد ربطت حسابًا قديمًا لك مع نسخة ويندوز هذه، ستلاحظ بدء مزامنة رسائل البريد الإلكتروني، حيث ستبدأ الإشعارات تظهر لك في منطقة الإشعارات الموجودة في الزاوية اليسرى السفلى (بجوار الساعة). انقر على أيقونة الإشعارات كما في الشكل التالي لترى رسائل البريد الجديدة: إذا لم تتم عملية المزامنة مباشرةً، فيمكنك الذهاب فورًا إلى تطبيق البريد الإلكتروني الافتراضي عبر النقر على زر ابدأ، وبعد ظهور قائمة البداية، اكتب مباشرةً باستخدام لوحة المفاتيح كلمة "البريد" ليعمل ويندوز على البحث عن تطبيق البريد الإلكتروني ومن ثمّ إظهاره لك في نتائج البحث ضمن نفس القائمة. انقر أيقونة التطبيق، لتبدأ عمليّة مزامنة البريد الإلكتروني فورًا. توجد في الواقع الكثير من الفوائد لربط نسخة الويندوز بحساب مايكروسوفت. عاينّا أحد هذه الفوائد قبل قليل، توجد العديد من الفوائد الأخرى كربط خدمة One Drive الخاصة بمايكروسوفت والتي تسمح لك بالتخزين السحابي، كما يمكنك الاستفادة من إمكانية الوصول إلى متجر ويندوز وتنزيل أو شراء التطبيقات التي تحتاجها. سنعاين العديد من هذه المزايا لاحقًا في هذه السلسلة. الخلاصة تعلّمنا من خلال هذا الدرس كيفيّة إجراء التحديثات اللازمة لويندوز، ولبرنامج الحماية الخاص به وهو Windows Defender. كما تعلّمنا كيفيّة ربط نسخة ويندوز 10 التي لديك، بحساب مايكروسوفت تمتلكه مسبقًا، أو حساب مايكروسوفت تنشئه بشكل جديد تمامًا. سنتعرّف في الدروس التالية في هذه السلسلة على كيفيّة الاستفادة من مزايا الربط مع حساب مايكروسوفت، بالإضافة إلى التعرّف إلى العديد من المزايا المفيدة التي يوفّرها ويندوز 10 للمستخدمين.
  8. سنتحدّث في هذا المقال من سلسلة المقالات حول التعامل مع ويندوز 10 عن كيفيّة تثبيت ويندوز 10 وذلك باستخدام أسلوب التنصيب من ذاكرة USB. السبب في اختياري هذا الأسلوب هو أنّه في بعض الحالات قد تحتاج إلى تنصيب ويندوز 10 على حاسوب غير متصل بشبكة الانترنت حاليًا أو لا يحتوي على أيّ نظام تشغيل مسبقًا أو أنّه يحتوي على نظام تشغيل غير متوافق مع ويندوز. لذلك فستحتاج إلى الحصول على قرص DVD يحتوي على نسخة ويندوز 10 وقد يكون الحاسوب لا يحوي محرك أقراص مدمجة DVD عندها لابد أن تلجأ إلى أسلوب عمليّ أكثر يتمثّل في تنصيب ويندوز 10 عن طريق ملف ISO والذي سنتحدث عنه في هذا المقال. الحصول على نسخة ويندوز 10 سنقوم بتنصيب الإصدار Windows 10 Pro لذلك سنقوم بالحصول عليه من موقع مايكروسوفت. انتقل إلى هذه الصفحة التي تسمح لنا بتحميل نسخة صورة ISO من ويندوز 10. انظر إلى الشكل التالي: استخدم شريط التمرير للوصول إلى القائمة المنسدلة الخاصة بتحديد إصدار ويندوز الذي نرغب بتحميله. اختر الإصدار Windows 10 من هذه القائمة كما في الشكل التالي: بعد اختيار هذا الإصدار انقر الزر "تأكيد" لكي تظهر لك خيارات أخرى تتعلّق باللغة التي ترغب بأن يدعمها نظام التشغيل. اختر اللغة العربية ثم انقر زر "تأكيد" الذي يظهر أسفل قائمة تحديد اللغة كما في الشكل التالي: في نهاية المطاف ستزودك هذه الصفحة برابطيّ تحميل. الأوّل خاص بنسخة 32 بت، والثاني خاص بنسخة 64 بت. علمًا أنّ هذه الرّوابط تكون صالحة خلال 24 ساعة فقط. اختر نسخة 64 بت كما في الشكل التالي: ستبدأ عملية التحميل التي قد تستغرق بعض الوقت تبعًا لسرعة الاتصال لديك. علمًا أنّ حجم النسخة يقارب 3.8 جيجا بايت. نسخ ملف ISO إلى ذاكرة USB بعد الانتهاء من عمليّة التحميل ينبغي أن ننسخ ملف ISO الذي حصلنا عليه إلى ذاكرة USB. سنجعل هذه الذاكرة إقلاعية Bootable USB Flash Memory عن طريق استخدام برنامج مخصّص لهذا الغرض. وللقيام بذلك سنستخدم برنامج اسمه Rufus وهو برنامج مجانيّ ومفتوح المصدر، وسهل الاستخدام إلى حدّ كبير. يمكن الحصول على هذا البرنامج من هذا الرابط. أدرج ذاكرة USB الخاصة بك والتي يجب أن تكون سعتها 4 جيجا بايت على الأقل. ثمّ شغل برنامج Rufus الذي حصلت عليه قبل قليل. لاحظ في البداية أنّ البرنامج سيتعرّف على ذاكرة USB التي أدرجتها، ويظهرها ضمن قائمة الأجهزة Device في الأعلى كما يظهر في الشكل التالي: بالنسبة إليّ، اسم ذاكرة USB الخاصة بي: WIN10_64_AR كما يظهر من الشكل السابق. لاحظ أيضًا الزر الصغير الموجود في الأسفل والذي أحطته بمستطيل أحمر صغير. يسمح هذا الزر باختيار نسخة ملف ISO الذي نزّلناه مسبقًا وذلك لوضع هذه النسخة على ذاكرة USB. انقر هذا الزر، ومن مربّع الحوار الذي سيظهر اختر ملف ISO الذي يمثّل نسخة ويندوز 10 التي قمنا بتنزيلها، ولاحظ كيف أنّ البرنامج يتعرّف على محتوى ملف الـ ISO ويُظهر لك جميع المعلومات المتعلّقة به: اترك هذه الإعدادات كما هي بدون تعديل. يمكنك الآن نقر زر Start ليعرض لك البرنامج رسالة تحذير بأنّ محتويات ذاكرة USB سيتم محوها. بعد موافقتك على ذلك ستبدأ عملية النسخ التي ستستغرق قليلًا من الوقت. بعد الانتهاء من عملية نسخ ملف ISO إلى ذاكرة USB سيعرض لك البرنامج رسالة READY من جديد ليخبرك أنّ عملية النسخ قد انتهت، وبذلك أصبحت هذه الذاكرة جاهزة الآن لأن يتم تنصيب نظام ويندوز منها. تنصيب ويندوز 10 احرص على ضبط خيار الإقلاع من ذاكرة USB في أيّ حاسوب ترغب بتنصيب ويندوز 10 عليه، وذلك من خلال إعدادات BIOS الخاصة به. عند الإقلاع من ذاكرة USB هذه سيعمل برنامج الإعداد الخاص بويندوز 10 ضمن سلسلة من الخطوات البسيطة التي ستتوّج بتنصيب ويندوز 10 على هذا الحاسوب. تبدأ هذه الخطوات بنافذة تخبرنا بنوع اللغة وإعدادات نسخة ويندوز التي سيتم تنصيبها على هذا الجهاز. حدّد الخيارات كما هو موضّح في الشكل السابق (أو حسبما ترغب) ثم انقر زر التالي. ستظهر نافذة أخرى انقر منها زر "التثبيت الآن". ستظهر بعد ذلك نافذة تنشيط ويندوز. أدخل فيها الرقم التسلسلي للنسخة التي لديك ثم انقر زر التالي. أمّا إذا لم تكن تمتلك رقمًا تسلسليًّا وأردت تجربة ويندوز 10 فيمكنك نقر "مفتاح المنتج غير موجود لدي" الموجود بجواز زر "التالي". ستخيّرنا النافذة التالية بين الإصدارين Windows 10 Home و Windows 10 Pro. اختر Windows 10 Pro ثم انقر زر "التالي". بعد ذلك ستظهر نافذة الترخيص. يمكنك تفقّد بنودها، ثم وافق عليها، وانقر زر "التالي". ستظهر بعد ذلك نافذة تحديد نوع التثبيت المرغوب به. كما في الشكل التالي: اختر الخيار الأول إذا أردت ترقية نظام الويندوز القديم الموجود أصلًا في الحاسوب أو يمكنك اختيار الخيار الثاني "مخصص" لتظهر بعد ذلك نافذة تحديد محرّك الأقراص المرغوب لتثبيت ويندوز ضمنه. يمكنك من خلال هذه النافذة تهيئة محركات الأقراص، وإنشاء أقراص جديدة، وحذفها. بعد اختيار محرّك الأقراص المناسب، انقر زر "التالي" لكي تبدأ عملية النسخ والإعداد. ستستغرق هذه العملية بعضًا من الوقت، بحسب سرعة جهاز الحاسوب لديك. بعد الانتهاء سيعرض برنامج الإعداد نافذة تستطيع من خلالها تحديد فيما إذا أردت استخدام الإعدادات السريعة أو أنّك تريد استخدام خيار التخصيص. سنختار هنا "استخدام الإعدادات السريعة". ستظهر بعد ذلك نافذة تسمح لك بكتابة اسم المستخدم الذي سيستخدم هذا الحاسوب، بالإضافة إلى تعيين كلمة مرور مناسبة، وتلميح لها، ثم انقر زر "التالي". عند هذه النقطة تكون عملية تنصيب ويندوز 10 قد انتهت، وسيظهر لك سطح المكتب للمرّة الأولى. الخطوة الأولى التي ينبغي القيام بها بعد تنصيب ويندوز هي التشبيك مع الإنترنت وتحديث ويندوز. وهذا ما سنتحدّث عنه بالإضافة إلى مواضيع أخرى في الدرس التالي. الخلاصة تعلّمنا من خلال هذا الدرس كيفيّة تنزيل نسخة ISO لويندوز 10 ونسخها إلى ذاكرة USB عن طريق برنامج اسمه Rufus، ثم نصّبنا ويندوز 10 من خلال ذاكرة USB بعد أن جعلنا الحاسوب يُقلع منها. إذا كنت تعمل في حقل الدعم الفني IT ربما ستجد هذه الطريقة مفيدة للغاية عند تنصيب ويندوز 10 على أكثر من حاسوب بنفس الوقت، حيث تستفيد من ميزة عدم إشغال الشبكة الخاصة بالشركة بتحميل نسخة الويندوز مباشرةً من الانترنت. أو عندما ترغب بتنصيب ويندوز 10 مباشرةً على حاسوب لا يحتوي على أيّ نظام تشغيل بشكل مسبق. سنتابع عملنا في هذه السلسلة في إجراء التحديث الأوليّ لويندوز 10 والتعرّف على المزايا الجديدة والمهمّة لنظام التشغيل الواعد من مايكروسوفت.
  9. سنتحدّث في هذا الدرس من سلسلة المقالات حول التعامل مع ويندوز 10 عن بعض التطبيقات المفيدة في ويندوز 10 والموجودة بصورة مسبقة في نظام التشغيل، وهي مجانية بالطبع. توجد العديد من التطبيقات من هذا النوع مثل تطبيقات الرياضة Sport والأخبار News والمال Money والخرائط Maps والملاحظات OneNote والطقس Weather. سنخصّ بالذكر التطبيقات الثلاثة الأخيرة. تطبيق الخرائط Maps هو من التطبيقات المفيدة في ويندوز 10 ويعطيك المزايا الأفضل بالنسبة لخرائط Bing وخرائط HERE. يتمتع هذا التطبيق بالعديد من المزايا التي سنستعرض بعضًا منها بعد قليل. انقر زر ابدأ واكتب مباشرةً كلمة "الخرائط" ليعمل ويندوز على البحث مباشرةً عن هذا التطبيق وإظهار نتيجة البحث المناسبة في الأعلى. انقر على أيقونة التطبيق لتظهر النافذة التالية: بعد أن تنقر زر "لنبدأ" ستظهر رسالة من التطبيق تسألك إذا كنت تريد السماح له بالوصول إلى موقعك الحالي. أجب بنعم، وانتظر قليلًا حتى تظهر النافذة الرئيسية له. ستظهر صورة عامّة للعالم، وتظهر فيها أيقونة دائرية صغيرة تُظهر موقعك التقريبي بهامش خطأ لا يتجاوز 7 كم. السبب في هامش الخطأ الكبير هذا، هو أنّني أشغّل هذا التطبيق من حاسوبي الشخصي الذي لا يمتلك جهاز GPS لتحديد المواقع. في حال تمّ تشغيل هذا التطبيق من جهاز يحتوي على جهاز GPS فسيكون موقعك دقيقًا على الخريطة. توجد العديد من المزايا المفيدة التي يمتلكها هذا التطبيق من بينها: يسمح للمستخدم بتثبيت المواقع المفضّلة ضمن شاشة البدء للوصول السريع لها فيما بعد. ويمكن استخدام هذا التطبيق على أجهزة الحاسوب المكتبيّة، كما يمكن استخدامه على الأجهزة الذكية المشغلة لنظام ويندوز، ويمكن استخدامه أيضًا مع نظارات مايكروسوفت الافتراضيّة Holographic. حفظ أي موقع جغرافي موجود على الخريطة، وإمكانية الوصول إليه من أي جهاز مرتبط بحساب مايكروسوفت الخاص بك. بالإضافة إلى حفظ نتائج البحث ومشاركتها باستخدام البريد الإلكتروني أو باستخدام برنامج OneNote الذي سنتحدّث عنه لاحقًا. يمكن مراقبة الحالة المروريّة للطرق بصورة حيّة مباشرة، إذا كانت توجد كاميرات مرورية تدعم النقل المباشر مثبتة على مثل هذه الطرق. يمكن تحميل الخرائط على الجهاز لاستخدامها لاحقًا دون الحاجة للاتصال بالإنترنت. توجد أدوات قياس جيدة لقياس المسافات على الخريطة يمكن الوصول إليها من خلال شريط الأدوات الموجود في الأعلى. يمكن من خلال هذه الأدوات قياس أي مسافة على الخريطة بالطول الحقيقي. تطبيق الملاحظات OneNote وهو أحد تطبيقات حزمة Office موجود بشكل مبسّط ومجاني في ويندوز 10 لكنّه مفيد. يستند هذا التطبيق على الصفحات في تدوين الملاحظات، حيث ينبغي إنشاء صفحات ذات تصنيف منطقي بما يلائم حاجات المستخدم. انقر زر ابدأ ثم اكتب بشكل مباشر الكلمة OneNote ليعمل ويندوز على إظهار أيقونة هذا التطبيق ليسمح لك بتشغيله. يمكن إنشاء صفحة جديدة من الجهة اليمنى لنافذة التطبيق، ثم نضع لها عنوانًا مناسبًا ونبدأ بتدوين الملاحظات التي تتنوّع بين ملاحظات نصيّة بسيطة أو محتوى غني يشتمل على إمكانيّة إدراج ملفات كاملة، أو حتى إدراج صورة ملتقطة مباشرةً من كاميرا الحاسوب (أو من كاميرا الجهاز الذكي). يمكن أيضًا إدراج ملاحظة على شكل رسم يتم رسمه مباشرةً (انظر لسان التبويب "رسم") باستخدام الفأرة. في الحقيقة ستكون ميزة الرسم مفيدة للغاية في حال كنت تستخدم حاسوبًا لوحيًا يمتلك قلمًا (مثل سلسلة حواسيب Surface). يمكن مزامنة الملاحظات بين جميع الأجهزة التي تستخدمها. وهذا يُعتبر أمرًا مهمًّا سواءً على المستوى الشخصي، أو حتى على مستوى العمل. حيث من الممكن مشاركة هذه الملاحظات مع أشخاص آخرين في حال رغبنا بذلك. تطبيق الطقس Weather رغم التنوّع الذي يمكن أن تجده في مثل هذه الصنف من التطبيقات، إلّا أنّ تطبيق الطقس الخاص بويندوز 10 له نكهة خاصّة! يرتبط هذا التطبيق في البداية بحساب مايكروسوفت الذي تستخدمه في تسجيل الدخول إلى ويندوز، ليضفي لمسة شخصيّة عليه. انقر زر ابدأ ثم اكتب مباشرةً كلمة "الطقس" ليعمل ويندوز على إظهار أيقونة هذا التطبيق. شغّل هذا التطبيق لتظهر نافذة الترحيب التالية: يمكنك أن تبحث عن موقعك الحالي من مربع "بحث" في الأسفل، أو أن تطلب من التطبيق معرفة موقعك الحالي بالنقر على الاختيار "اكتشف موقعي". إذا اخترت الأسلوب الأخير سيطلب منك ويندوز الموافقة على السماح لتطبيق الطقس بالوصول إلى موقعك. اقبل بذلك لكي يحدّد التطبيق موقعك الحالي. انقر زر بدء لكي يحمّل التطبيق بيانات الطقس الخاص بالموقع المحُدّد. انظر الشكل التالي: يمكنك عرض البيانات بشكل مختصر أو على بشكل تفصيلي كما يظهر من الشكل السابق. كما يمكنك استخدام شريط التمرير للوصول إلى أسفل الصفحة والاطلاع على بيانات متنوعة وغنيّة حول حالة الطقس والتنبؤ الجوي. الميزة الفريدة في هذا التطبيق هي ميزة "الخرائط" والتي يمكن الوصول إليها عن طريق النقر على الزر الموضّح في الشكل التالي وهو يقع ضمن الشريط العمودي الموجود على الطرف الأيمن من نافذة التطبيق. تعرض هذه الميزة تغيرات درجة الحرارة للمنطقة المطلوبة على شكل عرض فيديو تفاعلي على طول ساعات اليوم الواحد. انظر الشكل التالي: يمكن عرض نفس الخريطة التفاعلية السابقة ولكن بالنسبة لهطول الأمطار وصور الأقمار الصناعية والسُحُب أيضًا وذلك بالاختيار المناسب من القائمة الموجودة في الأعلى. يسمح هذا الفيديو التفاعلي بمراقبة تغيّرات الحالة الجويّة ابتداءً من الساعة الحالية وحتى اليوم التالي بنفس الساعة أي على مدار يوم كامل. يوفّر التطبيق أيضًا ميزة عرض بيانات قديمة للطقس لأغراض احصائيّة. الخلاصة تعرّفنا في هذا المقال على بعض التطبيقات المفيدة والمجّانيّة في ويندوز 10. وهي تطبيقات الطقس Weather والملاحظات OneNote والخرائط Maps. توجد العديد من التطبيقات الأخرى المجانيّة أيضًا في ويندوز 10 والتي لا يسعفنا المقال الحالي للحديث عنها. يمكنك أن تتعرّف عليها بنفسك لكي تستخدمها بالشكل الذي يناسب احتياجاتك.
  10. سنبدأ في هذا الدرس من سلسلة إعداد واستخدام ماجنتو بالتعرف على كيفيّة إضافة المنتجات البسيطة إلى ماجنتو. حيث سنعمل على اتباع الخطوات اللازمة لإضافة منتج بسيط. سيكون هذا الدرس كحجر بناء لإضافة العديد من أنواع المنتجات الأخرى -كما سنرى في درس لاحق- وذلك لأنّ المنتج البسيط كما وسبق أن أوضحنا سابقًا، يدخل في تكوين العديد من أنواع المنتجات الأخرى التي يدعمها ماجنتو. من المفيد أن تكون قد اطلعت على الدرس الخاص بأنواع المنتجات في ماجنتو. بدايةً وقبل إضافة أي منتج، يتوجّب علينا إضافة فئة (صنف) Category واحدة على الأقل يتبع لها المنتج. سنتحدّث في البداية عن كيفيّة إضافة مثل هذه الفئات، ثم ننتقل إلى عمليّة إضافة المنتجات. إنشاء فئة Category جديدة انتقل إلى القائمة الجانبيّة الخاصّة بمدير النظام واختر منها PRODUCTS، ومن القائمة الصغيرة التي ستظهر اختر الفئات Categories. بعد أن تظهر الصفحة المطلوبة انقر الزر Add Subcategory الموجود في أعلى ويسار الصفحة وذلك لإضافة فئة فرعية إلى الفئة الافتراضية Default Categroy. لتظهر بعد ذلك الصفحة المسؤولة عن إضافة فئة جديدة. كما في الشكل التالي: اختر الاسم T-Shirts للحقل Category Name. لاحظ معي وجود العديد من الخيارات المتعلّقة بالفئة المراد إضافتها. والتي تتعلّق بالمحتوى وبكيفيّة الظهور وبالتصميم، وحتى بالمنتجات التابعة لها. سنكتفي بكتابة اسم هذه الفئة حاليًا. انقر الآن زر Save البرتقالي اللون في الجهة العليا اليمنى من الصفحة. إنشاء منتج بسيط Simple Product بعد إضافة الفئة السابقة يمكننا الآن إضافة منتج بسيط، وذلك بالانتقال إلى القائمة الجانبيّة الخاصّة بمدير النظام، واختيار PRODUCTS، ومن القائمة الصغيرة التي ستظهر سنختر Catalog. بعد ظهور الصفحة المطلوبة. انقر السهم الصغير الموجود ضمن الزر البرتقالي اللون المسمى Add Products (في الجهة اليمنى العليا) لتظهر قائمة صغيرة، اختر منها Simple Product. أي أنّنا نريد إضافة منتج بسيط جديد. ستظهر الصفحة الخاصة بإضافة منتج بسيط. تحتوي هذه الصفحة على العديد من الخيارات المصنّفة والتي تضبط سلوك هذا المنتج. سنعمل على ضبط الحقول العامة التالية لهذا المنتج الجديد: الحقل Product Name سيحمل القيمة Hsoub T-Shirt. الحقل Price سيحمل القيمة 20. الحقل Quantity سيحمل القيمة 50. أمّا بالنسبة للحقل Categories فسنختار من القائمة المنسدلة الفئة التي أنشأناها في الفقرة السابقة وهي T-Shirts. بعد ذلك يمكنك استخدام شريط التمرير للانتقال أسفل الصفحة إلى التصنيف Content الذي يُعبّر عن محتوى الصفحة الخاصّة بهذا المنتج، انقر على المؤشّر الصغير الموجود على يمين هذا التصنيف لنشر محتواه كما يظهر في الشكل التالي: اكتب وصفًا عامًا للمنتج ضمن الحقل Description، ووصفًا مختصرًا له ضمن الحقل Short Description الذي يظهر بعد الحقل السابق (حقل Description): ثم انتقل بعد ذلك باستخدام شريط التمرير إلى الأسفل إلى التصنيف Images And Videos لإضافة صورة أو مقطع فيديو إن أحببت. بعد ذلك انقر زر الحفظ البرتقالي Save الذي يظهر أعلى يمين الصفحة ليتمّ إضافة هذا المنتج البسيط. من الممكن أن تكون قد لاحظت أيضًا الوجود العديد من الخيارات الأخرى التي يمكن ضبطها لهذا المنتج. ولكنّنا وبغرض تبسيط الأمور اعتمدنا على الخيارات الأدنى لإنشائه. زيارة صفحة المتجر لاستعراض المنتج الجديد من الجميل أن نتفقّد الآن صفحة الويب الخاصة بالمتجر لتفقّد الإضافات الجديدة التي عملنا عليها في الفقرات السابقة. افتح لسان تبويب جديد من متصفّح الإنترنت لديك. ثم اكتب العنوان التالي: http://127.0.1.1/magento سيؤدّي ذلك إلى الانتقال إلى الصفحة الرئيسيّة للموقع، والتي من المفترض أن تظهر للعميل عند زيارته للموقع بشكل عام. انظر الشكل التالي: من الملفت للنظر بدايةً أنّ الصفحة الرئيسية للموقع فارغة من المحتوى. وهذا أمر طبيعي تمامًا لأنّنا لم نجهّز المحتوى بعد. سنتناول هذا الموضوع في درس لاحق. نلاحظ الآن ظهور الفئة الجديدة T-Shirts على شريط الفئات في الأعلى. إذا حاولت نقر هذه الفئة، سينتقل بك المتصفّح إلى صفحة المنتجات الخاصة بهذه الفئة. انظر الشكل التالي: لا يوجد حاليًا سوى منتج واحد فقط، وهو Hsoub T-Shirt الذي أضفناه قبل قليل. أنصحك بإضافة المزيد من المنتجات لترى تأثير ذلك. انقر على هذا المنتج الوحيد، لتظهر الصفحة التفصيليّة للمنتج، والتي ستحتوي على جميع المعلومات التي كتبناها مسبقًا حوله. انظر إلى الشكل التالي: يمكننا أيضًا البحث عن المنتج باستخدام ميزة البحث الموجودة في ماجنتو. انتقل إلى الصفحة الرئيسية للمتجر مرّة أخرى. ثم من الزاوية اليمنى العليا ستلاحظ وجود مربّع خاص للبحث ضمن المتجر. اكتب كلمة البحث التي تريدها ولتكن T-Shirts مثلًا، ثم اضغط المفتاح Enter ليبدأ ماجنتو بالبحث وإيجاد المنتجات التي تتعلّق بالفئة T-Shirts. سيكون هناك كما هو واضح منتج واحد فقط حاليًا ضمن نتائج البحث. خلاصة تناولنا في هذا الدرس كيفيّة إنشاء فئة (صنف) Category جديدة للمنتجات في ماجنتو. وكيفيّة إضافة منتج بسيط Simple Product لهذه الفئة. يُعتبر المنتج البسيط كما أشرنا من قبل المنتج الأساسي الذي تُبنى عليه العديد من أنواع المنتجات الأخرى. سنتابع العمل على إضافة أنواع منتجات أخرى تعتمد في تكوينها على المنتج البسيط، وذلك في الدرس التالي.
  11. السبب هو الحاجة إلى السرعة الكبيرة. لا تنسى أنّ موقع يوتيوب هو موقع يتعامل في الأساس مع الفيديو. وهي بيانات ذات حجم كبير وثقل لا يستهان به في المعالجة. على العموم "حسب معلوماتي"، فإنّ شركة غوغل المالكة ليوتيوب لا تتعامل أصلًا مع PHP.
  12. الحقيقة لم أستطع تحديد المشكلة في هذا الكود. أحتاج إلى الحصول على نسخة من المشروع - على الأقل من صفحة التحميل مع الشيفرة الخاصة بها.
  13. هذا دليل ان الكود المسؤول عن رفع الملف غير صحيح. ادرج الكود المسؤول عن الرفع
  14. يعني عندما رفعت الملف simple.txt إلى السيرفر وجربت فتح الملف على السيرفر هل نجحت بفتحه وظهرت لك الكلمة Hello ؟
  15. أخي الكريم. لقد غيرت امتداد الملف الذي أرفقته إلي وجعلته html. ظهر الملف ضمن المتصفح كما في المرفق والذي يمثل كما أظن صفحة التحميل الرئيسية لتطبيقك. على ما يبدو أنّك لا تحفظ الملف ضمن قاعدة البيانات. إنما الذي تحفظه هو صفحة التحميل نفسها وهذا خطأ بالطبع.