قسمت پانزدهم ‫توسعه برنامه های Cross Platform با Xamarin Forms Bit Framework


در این قسمت قصد داریم تا با زدن کدهای Platform Specific در Xamarin آشنا شویم. صد البته که در Xamarin Forms به کتابخانه‌های NET. ای دسترسی داریم و مواردی چون Entity Framework Core، Auto Mapper، Autofac و … را می‌توانیم استفاده کنیم و در کنار اینها، مواردی چون Linq, Parallel Linq, Socket و … نیز در دسترس ما هستند. در رابطه با مواردی چون کار با...

در این قسمت قصد داریم تا با زدن کدهای Platform Specific در Xamarin آشنا شویم. صد البته که در Xamarin Forms به کتابخانه‌های NET. ای دسترسی داریم و مواردی چون Entity Framework Core، Auto Mapper، Autofac و … را می‌توانیم استفاده کنیم و در کنار اینها، مواردی چون Linq, Parallel Linq, Socket و … نیز در دسترس ما هستند. در رابطه با مواردی چون کار با Clipboard, Geocoding, Gyroscope, Secure Store و … نیز می‌توان از کتابخانه فوق العاده کاربردی Xamarin Essentials استفاده کرد که با یک کد CSharp می‌توانید روی Android/iOS/Windows جواب بگیرید. با ما همراه شوید.

اما فرض کنید که جستجو کرده اید و کد Cross Platform آماده‌ای برای استفاده نیافته‌اید؛ یا پیدا کرده‌اید، ولی صد در صد منطبق با نیازهای شما نیست. حال باید چه کنید؟ ابتدا باید کد مربوطه را بدانید که در Android/iOS/Windows (بسته به نیازتان) چگونه باید نوشت. در مورد Windows، خب تمامی امکانات سیستم عامل ویندوز را در زبان CSharp هم دارید. خبر خوب این است که این مهم نه تنها برای ویندوز که در مورد Android و iOS نیز برقرار است. به علاوه مستندات استفاده از آنها به زبان CSharp نیز موجود است. برای مثال نگاهی بیاندازید به روش Platform Specific استفاده از Bluetooth در Windows و AR Kit 2 در iOS و Job Scheduler در Android
صد البته که کتابخانه فوق العاده BluetoothLE وجود دارد و یک بار نوشتن کد، نه تنها روی Windows/Android/iOS که بر روی macOS و tvOS هم کار می‌کند!
با مثال گرفتن “ورژن برنامه” شروع می‌کنیم. هر چند با استفاده از Xamarin Essentials می شود با یک خط کد، ورژن برنامه را در هر پلتفرمی که باشیم گرفت؛ ولی فرض کنید که نمی‌شود. برای پیاده سازی این قابلیت ابتدا یک Interface را تعریف می‌کنیم و آن را در فولدر Contracts در پروژه XamApp قرار می‌دهیم:
public interface IAppVersionService { string GetAppVersion(); }

سپس در پروژه XamApp.Android، در فولدر Implementations، کلاس زیر را می‌سازیم: (چون این کلاس در پروژه Android است، به ۱۰۰% امکانات Android دسترسی داریم)

public class AndroidAppVersionService : IAppVersionService { public Android.Content.Context Context public string GetAppVersion() { return Context.PackageManager.GetPackageInfo(Context.PackageName, 0).VersionName; } }

این کد را از روی این جواب در StackOverFlow نوشته‌ام. همانطور که می‌بینید، دو کد، ساختاری شبیه به یکدیگر دارند. فقط تفاوت این است که Context.GetPackageManager در Java، در CSharp به Context.PackageManager تبدیل می‌شود؛ زیرا در Java چیزی به صورت Property و Get,Set وجود ندارد و Context.PackageManager در Java معادل می‌شود با دو متد Context.GetPackageManager و Context.SetPackageManager

تقریبا برای هر کاری در Android نیاز به Context دارید که می‌توانید آن را با Property Injection دریافت کنید.
سپس در فایل MainActivity.cs در کلاس XamAppPlatformInitializer، در متد RegisterTypes داریم:
containerBuilder.RegisterType() .As() .PropertiesAutowired(PropertyWiringOptions.PreserveSetValues);

برای پیاده سازی همین امکان در iOS داریم:

public class iOSAppVersionService : IAppVersionService { public string GetAppVersion() { var infoDictionary = NSBundle.MainBundle.InfoDictionary; return infoDictionary?["CFBundleShortVersionString"] as NSString; } }

که از روی این جواب به دست آمده است. البته جواب مربوطه علاوه بر ورژن، نام برنامه را نیز به دست می‌آورد که نیاز ما نیست. اگر سایر جواب‌ها را نگاه کنید، می‌بینید که جواب‌های مربوط به Swift برای برنامه نویسان CSharp خوانایی دارند، ولی این در مورد کدهای Objective-C خیلی صادق نیست(!) برای حل این مشکل، کد Objective-C را در این سایت به Swift تبدیل کرده و سپس معادل CSharp آن را بنویسید.

و در نهایت برای UWP از روی این جواب داریم:
public string GetAppVersion() { return $"."; }

که این دو نیز در AppDelegate.cs برای iOS و MainPage.xaml.cs برای UWP رجیستر می‌شوند.

برای استفاده نیز کافی است در هر View Model ای که قصد استفاده از این سرویس را دارید، یک Property از جنس IAppVersionService را تعریف کنید. در صورت Pull کردن آخرین تغییرات پروژه XamApp، می‌توانید نتیجه را در View و View Model با نام PlatformSpecificSamples ببینید.

خبر خوب این است که تمامی کدها به زبان CSharp نوشته می‌شوند و اگر مثلا وسط یک کد Platform Specific برای Android احتیاج به Auto Mapper پیدا کردید، می‌توانید از آن استفاده کنید. همچنین تمامی این کدها در Visual Studio دیباگ می‌شوند که خود نعمتی است.

حال اگر در ادامه کار، به یک کتابخانه ۳rd Party که با Java نوشته شده نیاز پیدا کردیم چه؟ برای مثال این کتابخانه اطلاعاتی را در مورد Ringer گوشی، در اختیار ما قرار می‌دهد!
در Xamarin می‌توانید فایل‌های JAR و AAR و Header‌های Objective-C و Swift را در پروژه اضافه کنید و Wrapper به زبان CSharp تحویل بگیرید! علاوه بر مستندات مفصل خود Xamarin در این مورد که برای Android/iOS می توانید آنها را بخوانید. افراد زیادی بر همین اساس امکان استفاده از کتابخانه‌های ۳rd Party زیادی را به Xamarin اضافه کرده‌اند. برخی از ابزارها نیز در این زمینه کاربردی هستند؛ برای مثال، برای ساخت C# Wrapper از روی C++,C از ابزار CppSharp می توانید استفاده کنید.
در نظر داشته باشید، اگر بخواهید کدی بزنید که فقط تفاوت رفتار در Android/iOS/Windows را دارد، یا بسته به گوشی، تبلت یا دسکتاپ بودن قرار است رفتارش تفاوت کند، مثلا یک پیام را فقط به دارندگان گوشی‌های اندرویدی نشان دهید، ولی با IUserDialogs که در هر سه پلتفرم کار می‌کند می‌خواهید این کد را بنویسید، احتیاجی به این کارها نیست و به سادگی تعریف یک Property با نام IDeviceService می‌توانید جواب لازم را بگیرید:
async Task ShowSomeAlertToAndroidPhoneUsersOnly() { if (DeviceService.RuntimePlatform == RuntimePlatform.Android DeviceService.Idiom == TargetIdiom.Phone) { await UserDialogs.AlertAsync("Some alert to android phone users only!", "Test"); } }
در برخی مواقع ما قصد سفارشی سازی کردن کنترل‌های UI را داریم. برای مثال زمانیکه از Entry در Xamarin Forms استفاده می‌کنیم، این به کنترل معادل Native خودش در هر پلتفرم تبدیل می‌شود، که همین باعث می‌شود بگوییم UI در Xamarin Forms به صورت Native است. حال در iOS که ما UITextField را به عنوان معادل Native کنترل Entry داریم، یک ویژگی داریم به نام ClearButtonMode که وقتی به مقدار WhileEditing تنظیم شود، در موقع تایپ کردن در UITextField، آن X پاک کردن متن باقی می‌ماند. این رفتار پیش فرض نیست و اگر ما قصد تغییر آن را داشته باشیم، یکی از متداول‌ترین راه‌ها، نوشتن Custom Renderer است. برای همین در iOS از EntryRenderer ارث بری می‌کنیم و سفارشی سازی مربوطه را انجام می‌دهیم و در نهایت EntryRenderer خودمان را رجیستر می‌کنیم.
public class XamAppEntryRenderer : EntryRenderer { protected override void OnElementChanged(ElementChangedEventArgs e) { base.OnElementChanged(e); if (e.NewElement != null) /* e.NewElement is a Xamarin Forms' Entry */ { Control.ClearButtonMode = UITextFieldViewMode.WhileEditing; // Control is UITextField } } }

برای Register کردن نیز داریم:

[assembly: ExportRenderer(typeof(Entry), typeof(XamAppEntryRenderer))]

در واقع این کد می‌گوید که از این به بعد، Entry‌ها در iOS، با کلاس جدید Render شوند. برای درک بهتر این مهم، فایل XamAppEntryRenderer.cs را در فولدر Renderer در پروژه XamApp.iOS مشاهده کنید.

dotnettips

مطالب پیشنهادی

قسمت پانزدهم ‫توسعه برنامه های Cross Platform با Xamarin Forms & Bit Framework
قسمت نهم‫ مهارت‌های تزریق وابستگی‌ها در برنامه‌های NET Core. تعریف سرویس‌های Open Generics
قسمت پانزدهم ‫توسعه برنامه های Cross Platform با Xamarin Forms & Bit Framework
آموزش ‫اعتبارسنجی شرطی فرم‌ها در MVC
قسمت پانزدهم ‫توسعه برنامه های Cross Platform با Xamarin Forms & Bit Framework
قسمت هشتم ‫مهارت‌های تزریق وابستگی‌ها در برنامه‌های NET Core. – ساده سازی معرفی سرویس‌ها توسط Scrutor
قسمت پانزدهم ‫توسعه برنامه های Cross Platform با Xamarin Forms & Bit Framework
قسمت هفتم ‫مهارت‌های تزریق وابستگی‌ها در برنامه‌های NET Core. کار با سرویس‌های متفاوتی با یک امضاء
قسمت پانزدهم ‫توسعه برنامه های Cross Platform با Xamarin Forms & Bit Framework
‫قسمت ششم مهارت‌های تزریق وابستگی‌ها در برنامه‌های NET Core. دخالت در مراحل وهله سازی اشیاء توسط IoC Container
قسمت پانزدهم ‫توسعه برنامه های Cross Platform با Xamarin Forms & Bit Framework
‫نصب و راه اندازی SQL Server بر روی لینوکس با استفاده از Docker
قسمت پانزدهم ‫توسعه برنامه های Cross Platform با Xamarin Forms & Bit Framework
هر چه باید در مور ‫MIME Sniffing و استاندارد OWASP بدانید
قسمت پانزدهم ‫توسعه برنامه های Cross Platform با Xamarin Forms & Bit Framework
قسمت چهارم ‫مهارت‌های تزریق وابستگی‌ها در برنامه‌های NET Core. – پرهیز از الگوی Service Locator در برنامه‌های وب
قسمت پانزدهم ‫توسعه برنامه های Cross Platform با Xamarin Forms & Bit Framework
‫قسمت پنجم مهارت‌های تزریق وابستگی‌ها در برنامه‌های NET Core. – استفاده از الگوی Service Locator در مکان‌های ویژه‌ی برنامه‌های وب
قسمت پانزدهم ‫توسعه برنامه های Cross Platform با Xamarin Forms & Bit Framework
موفقیت تیم دانشگاه امیرکبیر برای حضور در المپیک برنامه‌نویسی ۲۰۱۹
قسمت پانزدهم ‫توسعه برنامه های Cross Platform با Xamarin Forms & Bit Framework

حتما بخوانید: سایر مطالب گروه آموزش

برای مشاهده فوری اخبار و مطالب در کانال تلگرام ما عضو شوید!


منتخب امروز

بیشترین بازدید یک ساعت گذشته


انواع فونت و متن بسم الله الرحمن الرحیم برای بیو اینستا