كيفية إنشاء تطبيق Android و iOS في C # على جهاز Mac
نشرت: 2022-03-11ذات مرة ، كانت هناك شركة لديها أفضل الأدوات ، وكانت كتابة البرامج لمنصتها رائعة. لكن ببطء ، أصبحوا غير مبالين بمشاكلهم الخاصة. لم ينزعجوا عندما تحطمت أنظمتهم ، بل قبلوا حالة الكون هذه كحقيقة من حقائق الحياة. لقد اعتقدوا أن برامجهم كانت مثالية داخل أنفسهم ، هادئة وأنيقة ، والغرض منها واضح.
يا فتى ، إذا كانوا يعرفون فقط كم كانوا مخطئين ...
لقد تأخرت كثيرًا عندما أدركوا أخطائهم وبكى رئيسهم التنفيذي لإعادة جميع المطورين الذين تركوا منصتهم وأبحروا بعيدًا. كانت الشركة هي Microsoft وأنا ، على سبيل المثال ، كنت مقتنعًا بأن مصيرهم قد تم تحديده وأنهم سوف يموتون ببطء ولكن بثبات من طليعة المشهد التكنولوجي.
أنا سعيد جدًا لأنني كنت مخطئًا!
في السنوات القليلة الماضية ، سحبت Microsoft بضع ارسالا ساحقا من سواعدها. نعم ، لقد أفسدوا Skype (ما زلت أكرههم لذلك) ، وفشلوا في استخدام الهواتف الذكية ، وكادوا أن ينجحوا في استخدام الأجهزة اللوحية. لكنهم فعلوا بعض الأشياء المدهشة أيضًا. تخلوا عن نهج الإمبراطورية المغلقة ، فتحوا .NET المصدر ، وانضموا إلى Linux Foundation ، وأطلقوا SQL Server لنظام Linux ، وأنشأوا هذه الأداة الجديدة الرائعة المسماة Visual Studio for Mac.
هذا صحيح ، Microsoft IDE حقيقي ليس لنظام التشغيل Windows ، ولكن لنظام التشغيل Mac. تخيل ذلك!
كتابة أول تطبيق عبر النظام الأساسي لنظامي Android و iOS باستخدام C # على Mac
يمكنك استخدام Visual Studio for Mac لإنشاء أي نوع من التطبيقات تقريبًا. يمكن أن يكون iOS أو tvOS أو Android أو Mac أو .NET Core أو حتى ASP.NET. نظرًا لأن جميع الأطفال الرائعين يكتبون الآن تطبيقات الأجهزة المحمولة ، فلنلقِ نظرة على ما يتطلبه الأمر في Visual Studio for Mac لإنشاء تطبيق C # يعمل على Android و iOS.
أول شيء عليك القيام به هو اختيار قالب التطبيق. لنبدأ بـ "تطبيق Single View App" البسيط.
بعد ملء اسم الحزمة وتشغيل تطبيقك ، سيقوم Visual Studio بإنشاء حل بثلاثة مشاريع. سيكون المشروع الأول عبارة عن مكتبة مشتركة حيث يجب عليك الاحتفاظ بالرمز المستقل للنظام الأساسي ، وسيكون المشروعان الآخران عبارة عن تطبيقات Android و iOS.
يمكنك استخدام قائمة "تشغيل" ، أو الأوامر الموجودة في شريط التطبيق ، لبدء تطبيقك.
تهانينا! أنت الآن مطور iOS و Android بغض النظر عن حقيقة أنك لم تكتب أبدًا سطرًا من Objective-C أو Swift أو Java code.
بالرغم من ذلك ، لم ننجز الكثير حقًا مع تطبيقنا. لنجعل الأمور أكثر إثارة للاهتمام وندمج الخرائط وخدمات الموقع.
استخدام خدمات الخرائط والموقع
ضع في اعتبارك أن VS for Mac لا يزال في "معاينة" ولا يوجد الكثير من المساعدة والوثائق التي ستجدها حول استخدامه. أفضل مكان للإشارة إلى كيفية القيام بالأشياء هو وثائق Xamarin الرسمية.
لا يستخدم Visual Studio For Mac نفس الحل وبنية التطبيق مثل أدوات Xamarin التي ربما تكون قد شاهدتها على جهاز الكمبيوتر. في معظم الحالات ، سوف تحتاج إلى التجربة والتغلب على بعض العقبات للحصول على أمثلةهم للعمل. دعونا نأمل أن تظل Microsoft في صدارة لعبتها وتوفر مجموعة رائعة من موارد MSDN بمجرد إصدار الإصدار الأخير من VS for Mac.
عرض الموقع الحالي على iOS
يتطلب الوصول إلى موارد الجهاز المحمول ، مثل الموقع الحالي ، أن يمنح المستخدمون أذونات "يدويًا" لتطبيقك لاستخدام هذه الموارد. يستخدم iOS ملف info.plist لتخزين هذه الإعدادات. يوفر VS for Mac واجهة مرئية لتحرير هذا الملف. أول شيء يتعين علينا القيام به هو إضافة قيمة للإعداد المسمى NSLocationWhenInUseUsageDescription .
ملاحظة: سيُظهر VS اسمًا طويلاً لـ "NSLocationWhenInUseUsageDescription" عند تعيين اسم الخاصية. هذا متوقع ولا تقلق بشأنه.
تم إنشاء تطبيقنا الذي تم تمهيده باستخدام زر بسيط يقوم بحساب النقرات. أول شيء تريد القيام به هو إزالته واستبدال محتوى الشاشة بخريطة. للقيام بذلك ، ابحث عن ملف Main.storyboard في متصفح الحل وانقر عليه نقرًا مزدوجًا لفتحه في المحرر.
يتم تقديم القصص المصورة بواسطة Apple وتبنيها Xamarin أيضًا. راجع وثائق Apple أو وثائق Xamarin للحصول على مزيد من المعلومات.
قم بإزالة الزر وإضافة مكون عرض الخريطة إلى الصفحة.
تأكد من تسمية مكون "mapView" الخاص بك بشكل صحيح.
كل ما تبقى الآن هو تنظيف ملف ViewController.cs وتعديل طريقة ViewDidLoad() لمطابقة ما يلي:
using CoreLocation; public override void ViewDidLoad() { base.ViewDidLoad(); // Perform any additional setup after loading the view, typically from a nib. CLLocationManager locationManager = new CLLocationManager(); locationManager.RequestWhenInUseAuthorization(); mapView.ShowsUserLocation = true; }يمكنك استخدام ميزة "الإصلاح السريع" لجعل VS تضيف مرجعًا تلقائيًا إلى مكتبة CoreLocation أو يمكنك إضافتها يدويًا.
بعد تشغيل تطبيق iOS الخاص بك ، يجب أن ترى طلبًا للوصول إلى موقعك. بمجرد منح الإذن ، سيتم تحميل خريطتك بنقطة زرقاء قياسية توضح مكانك (أو المكان الذي تتظاهر فيه باستخدام محاكي iOS :)).
عرض الموقع الحالي على Android
لسوء الحظ ، قررت Google و Microsoft جعل هذه المهمة البسيطة أكثر تعقيدًا قليلاً مما كانت عليه مع iOS. لاستخدام الخرائط في تطبيق Android ، ستحتاج إلى إنشاء مفتاح API لخرائط Google وإضافته إلى ملف AndroidManifest.xml .
أنشأ شباب Xamarin دليلًا بسيطًا جدًا للحصول على مفتاح API لخرائط Google. يرجى اتباع الخطوات الواردة في دليلهم قبل المتابعة. عند الانتهاء ، يجب أن يحتوي ملف AndroidManifest.xml الخاص بك على إعداد مثل هذا:
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="YOUR KEY" />أنت الآن جاهز لإضافة خريطة لتطبيقك.
إن الشيء العظيم في VS for Mac هو أنه مدعوم من NuGet ، تمامًا مثل أخيه الأكبر. نظرًا لأن مكتبات التعامل مع الخرائط غير مضمنة افتراضيًا ، فستحتاج إلى تثبيت حزمة Xamarin.Forms.Maps .
ومع ذلك ، لا يوجد مكون "عرض الخريطة" يمكنك فقط سحبه إلى "النشاط". بدلاً من ذلك ، تتطلب إضافة خريطة إلى الشاشة تغيير الموارد يدويًا-> التخطيط-> ملف Main.axml. يمكنك استخدام عرض المصمم لحذف الزر الذي تم إنشاؤه من قبل ، ولكن بعد ذلك قم بالتبديل إلى "طريقة العرض Code" وإضافة رمز الجزء التالي في LinearLayout الخاص بك:
<fragment xmlns:andro android: android:layout_width="match_parent" android:layout_height="match_parent" class="com.google.android.gms.maps.MapFragment" /> كما هو الحال مع iOS ، ستحتاج إلى تكوين التطبيق الخاص بك للمطالبة بالأذونات المناسبة. للقيام بذلك ، افتح AndroidManifest.xml للتحرير وانقر فوق الزر "تطبيق" في الجانب الأيسر السفلي من المحرر. سيُظهر لك VS واجهة مرئية لتعيين هذه القيم. هناك عدد قليل منهم ستحتاج إلى تمكينه ، كما هو موضح أدناه.

حان الوقت الآن لكتابة بعض التعليمات البرمجية الحقيقية. ابحث عن ملف MainActivity.cs وافتحه للتحرير وقم بإجراء التغييرات التالية:
أضف مراجع مساحة الاسم:
using Android.Gms.Maps.Model; using Android.Gms.Maps; using Android.Locations; Make your MainActivity also a ILocationListener. public class MainActivity : Activity, ILocationListener Implement the ILocationListener methods within your MainActivity: public void OnProviderEnabled(string provider) {} public void OnProviderDisabled(string provider) {} public void OnStatusChanged(string provider, Availability status, Bundle extras) {} public void OnLocationChanged(Android.Locations.Location location) { LatLng latLng = new LatLng(location.Latitude, location.Longitude); CameraPosition.Builder builder = CameraPosition.InvokeBuilder(); builder.Target(latLng); builder.Zoom(15); builder.Bearing(155); builder.Tilt(10); CameraPosition cameraPosition = builder.Build(); CameraUpdate cameraUpdate = CameraUpdateFactory.NewCameraPosition(cameraPosition); MapFragment mapFrag = (MapFragment)FragmentManager.FindFragmentById(Resource.Id.map); GoogleMap map = mapFrag.Map; if (map != null) { map.MoveCamera(cameraUpdate); } }أضف المتغيرين التاليين كمتغيرات على مستوى الفئة:
LocationManager locMgr; string locationProvider; وقم بتنظيف طريقة OnCreate() لتبدو كما يلي:
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Set our view from the "main" layout resource SetContentView(Resource.Layout.Main); locMgr = GetSystemService(LocationService) as LocationManager; Criteria locationCriteria = new Criteria(); locationCriteria.Accuracy = Accuracy.Coarse; locationCriteria.PowerRequirement = Power.Medium; locationProvider = locMgr.GetBestProvider(locationCriteria, true); locMgr.RequestLocationUpdates(locationProvider, 2000, 1, this); } من خلال استدعاء GetSystemService من داخل أسلوب OnCreate() ، سيتم تنشيط MainActivity الخاص بك باعتباره ILocationListener وبالتالي سيكون قادرًا على التعامل مع جميع الأحداث المذكورة أعلاه.
قم بتشغيل تطبيق Android الخاص بك ويجب أن تحصل على الخريطة في موقعك ، على غرار الصورة التالية.
استخدام المكتبات المشتركة لنظامي التشغيل iOS و Android
تتمثل إحدى أعظم ميزات VS for Mac في إمكانية مشاركة التعليمات البرمجية بين تطبيقات iOS و Android. من الناحية المثالية ، يمكن أن يكون لدينا كل منطق الأعمال الخاص بالتطبيق في مكتبة مشتركة ، ونقصر أي كود خاص بنظام iOS و Android ليكون جزءًا من واجهة المستخدم.
لنقم بإنشاء فئة مشتركة تقوم بتنفيذ طلب HTTP بشكل غير متزامن وإظهار المحتوى في وحدة تحكم التصحيح.
قم بإنشاء ملف فصل دراسي جديد في مكتبتك المشتركة باسم RestClient.cs التالي:
(تأكد من استخدام مساحة الاسم الصحيحة من مشروعك)
using System; using System.Net; namespace testshared { public delegate void callback(string responseText); class ReqState { public ReqState(HttpWebRequest req, callback cb) { request = req; callback = cb; } public HttpWebRequest request { get; set; } public callback callback; } public class RestClient { public RestClient() {} public void FetchPage(string url, callback cb) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.BeginGetResponse(new AsyncCallback(FinishWebRequest), new ReqState(request, cb)); } private void FinishWebRequest(IAsyncResult result) { ReqState reqState = (result.AsyncState as ReqState); HttpWebResponse response = reqState.request.EndGetResponse(result) as HttpWebResponse; using (var reader = new System.IO.StreamReader(response.GetResponseStream())) { string responseText = reader.ReadToEnd(); reqState.callback(responseText); } } } }استخدام المكتبة على نظام iOS
قم بتعديل ملف ViewController.cs في مشروع iOS ليطابق الكود التالي:
(تأكد من استخدام مساحة الاسم الصحيحة من مشروعك)
using System; using UIKit; using System.Diagnostics; namespace testshared.iOS { public partial class ViewController : UIViewController { RestClient rest = new RestClient(); public ViewController(IntPtr handle) : base(handle) {} public override void ViewDidLoad() { base.ViewDidLoad(); // Perform any additional setup after loading the view, typically from a nib. Button.AccessibilityIdentifier = "myButton"; Button.TouchUpInside += delegate { Button.SetTitle("Loading...", UIControlState.Normal); rest.FetchPage("http://www.google.com", doneCallback); }; } public void doneCallback(string content) { InvokeOnMainThread(() => { Debug.Write(content); Button.SetTitle("All Done", UIControlState.Normal); }); } public override void DidReceiveMemoryWarning() { base.DidReceiveMemoryWarning(); // Release any cached data, images, etc that aren't in use. } } }قم بتشغيل تطبيق iOS الخاص بك ، وانقر فوق الزر وتحقق من علامة التبويب "إخراج التطبيق" في Visual Studio. يجب أن تعرض شيئًا مثل هذا:
استخدام المكتبة على Android
التغييرات المطلوبة في تطبيق Android مشابهة جدًا لتلك المطلوبة على iOS. قم بتعديل ملف MainActivity.cs لمطابقة ما يلي:
(تأكد من استخدام مساحة الاسم الصحيحة من مشروعك)
using Android.App; using Android.Widget; using Android.OS; namespace testshared.Droid { [Activity(Label = "testshared", MainLauncher = true, Icon = "@mipmap/icon")] public class MainActivity : Activity { RestClient rest = new RestClient(); protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Set our view from the "main" layout resource SetContentView(Resource.Layout.Main); // Get our button from the layout resource, // and attach an event to it Button button = FindViewById<Button>(Resource.Id.myButton); button.Click += delegate { button.Text = $"Loading..."; rest.FetchPage("http://www.google.com", doneCallback); }; } public void doneCallback(string content) { RunOnUiThread(() => { Button button = FindViewById<Button>(Resource.Id.myButton); button.Text = "All done"; System.Diagnostics.Debug.WriteLine(content); }); } } } ملاحظة: تتطلب بنية النظام لكل من النظامين الأساسيين ، Android و iOS ، حدوث كل تفاعلات واجهة المستخدم على سلسلة التطبيق الرئيسية. هذا يعني أن أي تغيير في عناصر واجهة المستخدم يجب أن يحدث من داخل السلسلة الرئيسية أيضًا. هذا هو المكان الذي يأتي فيه RunOnUiThread و InvokeOnMainThread . نظرًا لأن طلبات HTTP تم تنفيذها في سلسلة منفصلة وتم doneCallback() خارج سلسلة المحادثات الرئيسية ، كان علينا استخدام هذه الطرق حتى نتمكن من الوصول إلى الأزرار وتغيير التسمية.
C # المطورون يستولون على Android و iOS
لا يزال لدى Visual Studio for Mac بعض التجاعيد للعمل ، ولكن من النظرة الأولى إليه ، أنا متحمس جدًا بشأن مستقبله. تزداد الحاجة إلى تطبيقات الهاتف المحمول كل يوم ، ومع Visual Studio for Mac ، مكّنت Microsoft أيضًا جيشًا من مطوري C # العظماء لسد هذه الحاجة.
