افزونههای برنامه ماژولهای اجرایی جداگانهای هستند که قابلیتهای یک برنامه موبایل را فراتر از رابط اصلی آن گسترش میدهند: Today Widget در صفحه اصلی، پردازش تماس VoIP از طریق CallKit و واکنش به رویدادهای سیستم از طریق BroadcastReceiver. یکپارچهسازیهای سیستمی به برنامه اجازه میدهند تا با سیستم عامل در سطح عمیقی تعامل کند و قابلیتهایی را که برای صفحات عادی در دسترس نیستند، باز کند. طبق مستندات توسعهدهندگان اپل، هر افزونه در یک فرآیند ایزوله اجرا میشود و مستقل از برنامه اصلی توسط سیستم مدیریت میشود. افزونههای برنامه در یک برنامه موبایل امکان پیادهسازی قابلیتهایی را فراهم میکنند که در فرآیند اصلی در دسترس نیستند.
نکات کلیدی
افزونههای برنامه در iOS در iOS 8 ظاهر شدند و به پایه یکپارچهسازیهای سیستمی در توسعه موبایل تبدیل شدند. اینها باینریهای جداگانهای هستند که همراه با برنامه اصلی بستهبندی میشوند اما در یک فرآیند ایزوله راهاندازی میشوند. هر افزونه Info.plist مخصوص خود و نقطه ورودی تعریف شده از طریق NSExtensionPrincipalClass دارد. سیستم چرخه حیات افزونههای برنامه را مدیریت میکند — آنها پس از اتمام کار نمیتوانند در پسزمینه باقی بمانند.
WidgetKit (iOS 14+) یک چارچوب مدرن برای ایجاد ویجت در صفحه اصلی است. WidgetKit از SwiftUI برای توصیف رابط و TimelineProvider برای تعریف برنامههای بهروزرسانی استفاده میکند. ویجتها در سه اندازه عرضه میشوند: کوچک (2×2 سلول)، متوسط (4×2) و بزرگ (4×4). Today Widget قدیمی مبتنی بر UICollectionViewController همچنان پشتیبانی میشود، اما اپل مهاجرت به WidgetKit را توصیه میکند. افزونههای برنامه در WidgetKit از انیمیشن، ورودی صفحه کلید یا حرکات پشتیبانی نمیکنند — آنها عناصر ایستا یا شبهمتحرک با بهروزرسانی دورهای هستند.
Share Extension امکان ارسال محتوا از هر برنامهای به برنامه شما را از طریق برگه اشتراک سیستم فراهم میکند. Share Extension داده را از طریق NSExtensionItem دریافت میکند و از SLComposeServiceViewController برای رابط کاربری استفاده میکند. Action Extension محتوا را در محل پردازش میکند — برای مثال، متن را در مرورگر بدون تغییر به برنامه دیگر ترجمه میکند. هر دو نوع باید کار را در زمان محدودی تکمیل کنند، در غیر این صورت سیستم افزونه را "میکشد". این یک محدودیت مهم افزونههای برنامه در یک برنامه موبایل است — وظایف پسزمینه در سطح افزونه در دسترس نیستند.
یکپارچهسازیهای سیستمی در iOS بسیار فراتر از ویجتها هستند: CallKit، PushKit و SiriKit به یک برنامه موبایل اجازه میدهند در سطح سیستم کار کند. این چارچوبها به مجوزهای ویژه نیاز دارند اما تجربه یکپارچهای به کاربر میدهند — تماسها از طریق CallKit مانند تماسهای تلفنی معمولی به نظر میرسند و Siri بدون باز کردن برنامه، درخواستها را پردازش میکند.
CallKit تماسهای برنامههای شخص ثالث را در صفحه تماس سیستم، از جمله صفحه قفل شده، ادغام میکند. CXProvider برنامه را به عنوان سرویس VoIP ثبت میکند و CXCallController تماسها را مدیریت میکند. CallKit به طور خودکار تماسهای تکراری را مسدود میکند و از Call Directory Extension برای مسدود کردن شمارههای ناخواسته پشتیبانی میکند. یکپارچهسازیهای سیستمی در توسعه موبایل با CallKit برای برنامههای ارتباط صوتی حیاتی هستند — WhatsApp، Skype و Zoom از آن برای نمایش تماسهای ورودی استفاده میکنند.
PushKit اعلانهای فشاری را مستقیماً به برنامه موبایل بدون نمایش به کاربر تحویل میدهد. PushKit برنامه را از حالت "کشته شده" بیدار میکند و داده را از طریق نماینده PKPushRegistryDelegate منتقل میکند. این مکانیسم اصلی برای برنامههای VoIP است: PushKit اطلاعات تماس را تحویل میدهد و CallKit آن را نمایش میدهد. PushKit اولویت تحویل بالاتری نسبت به اعلانهای فشاری معمولی دارد و نیازی به نمایش بنر ندارد. افزونههای برنامه در برنامههای موبایل اغلب PushKit را با CallKit برای ارتباط صوتی ترکیب میکنند.
SiriKit امکان پردازش درخواستها را از طریق Siri و برنامه میانبرها فراهم میکند. Intents Extension یک افزونه برنامه جداگانه است که نیتهای پشتیبانی شده را ثبت و پردازش میکند. SiriKit از بیش از 20 دامنه پشتیبانی میکند: تماسها، پیامها، پرداختها، یادداشتها، تمرینات. میانبرها به کاربر امکان ایجاد خودکارسازی را میدهند — برای مثال، "ارسال پیام در WhatsApp از طریق Siri". یکپارچهسازیهای سیستمی با SiriKit و میانبرها تعامل را افزایش میدهند زیرا کاربر بدون باز کردن برنامه اقدامات را انجام میدهد.
BroadcastReceiver مؤلفه اندروید است که به پیامهای پخش سیستمی واکنش نشان میدهد. برخلاف افزونههای برنامه iOS، BroadcastReceiver به باینری جداگانه نیاز ندارد — فقط کافی است گیرنده را در مانیفست یا در کد از طریق Context.registerReceiver ثبت کنید. یکپارچهسازیهای سیستمی در اندروید اغلب با BroadcastReceiver شروع میشوند: از شروع یک سرویس هنگام بوت دستگاه تا واکنش به اتصال شبکه.
IntentFilter BroadcastReceiver را به یک رویداد سیستم خاص متصل میکند. رویدادهای معمول: BOOT_COMPLETED (بوت دستگاه)، CONNECTIVITY_ACTION (تغییر شبکه)، BATTERY_LOW (کم بودن باتری)، TIME_SET (تغییر زمان). گیرنده در AndroidManifest.xml یا از طریق Context.registerReceiver برای ثبت پویا ثبت میشود. ثبت پویا ترجیح داده میشود — به مجوزهای مانیفست نیاز ندارد و فقط زمانی که برنامه فعال است کار میکند. افزونههای برنامه در اندروید به عنوان یک مفهوم وجود ندارند، اما BroadcastReceiver نقش مشابهی ایفا میکند — قابلیتهای برنامه را از طریق یکپارچهسازیهای سیستمی گسترش میدهد.
NotificationListenerService سرویسی است که همه اعلانهای سیستم را دریافت میکند. NotificationListenerService به مجوز BIND_NOTIFICATION_LISTENER_SERVICE و دسترسی از طریق تنظیمات دسترسی نیاز دارد. AccessibilityService ابزار قدرتمندتری برای یکپارچهسازی سیستمی است: میتواند محتوای صفحه را بخواند، کلیکها را شبیهسازی کند و اقدامات را خودکار کند. هر دو سرویس نیاز به فعالسازی صریح توسط کاربر در تنظیمات دارند که امنیت را افزایش میدهد. یکپارچهسازیهای سیستمی در برنامههای موبایل از طریق AccessibilityService برای پرکنندههای خودکار، صفحهخوانها و ابزارهای دسترسی استفاده میشوند.
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
WorkManager.getInstance(context)
.enqueueUniqueWork("post-boot", ...)
}
}
}
مثال یک BroadcastReceiver را برای رویداد BOOT_COMPLETED ثبت میکند. WorkManager برای اجرای وظایف تأخیری پس از بوت دستگاه استفاده میشود — این رویکرد استاندارد برای برنامههای اندروید است.
App Widget Provider در اندروید معادل افزونههای برنامه iOS در زمینه ویجت است: مؤلفهای است که محتوای تعاملی را در صفحه اصلی نمایش میدهد. برخلاف WidgetKit، ویجتهای اندروید میتوانند ورودی کاربر — کلیکها، کلیدها و حرکات — را بپذیرند. App Widget Provider از طریق توصیف XML اندازه و فرکانس بهروزرسانی در مانیفست ثبت میشود.
RemoteViews رابط ویجت را از طریق یک طرح XML توصیف میکند و فقط از مجموعه محدودی از Viewها پشتیبانی میکند. RemoteViews به Viewهای سفارشی اجازه نمیدهد — فقط مؤلفههای استاندارد: TextView، ImageView، Button، ProgressBar. AppWidgetProvider کلاس پایهای است که بهروزرسانیها، فعالسازی و حذف ویجت را مدیریت میکند. متد onUpdate از طریق تایمر با updatePeriodMillis یا از طریق WorkManager برای کنترل دقیق فراخوانی میشود. یکپارچهسازیهای سیستمی با ویجتها در اندروید نیاز به احتیاط دارند — بهروزرسانی بیش از حد مکرر باتری را تخلیه میکند.
Glance API کتابخانه Jetpack برای ایجاد ویجت با استفاده از Kotlin DSL به جای XML است. Glance API به RemoteViews کامپایل میشود و از نحوی شبیه به Compose پشتیبانی میکند: GlanceComposable، Column، Row، Text. این کتابخانه مشکل کد XML پیچیده را حل میکند و امکان آزمایش ویجتها را از طریق JUnit فراهم میکند. Glance API هنوز از همه قابلیتهای RemoteViews پشتیبانی نمیکند — برای ویجتهای تعاملی پیچیده، رویکرد کلاسیک بهتر است. افزونههای برنامه در توسعه موبایل در اندروید به سمت Glance API در حال تکامل هستند و ایجاد و نگهداری ویجتها را سادهتر میکنند.
Content Provider مؤلفه اندروید برای اشتراکگذاری دادههای ساختاریافته بین برنامهها از طریق رابط یکپارچه ContentResolver است. برخلاف افزونههای برنامه iOS، Content Provider یک فرآیند جداگانه ایجاد نمیکند — داده به صورت همزمان در زمینه برنامه فراخواننده درخواست میشود. Content Provider پایه یکپارچهسازیهای سیستمی در اندروید است: مخاطبین، فایلهای رسانه، تقویم و برنامههای استاندارد از آن برای انتشار داده استفاده میکنند.
FileProvider زیرکلاسی از ContentProvider برای انتقال امن فایل بین برنامهها است. FileProvider به جای مسیرهای مستقیم file:// که در اندروید 7+ ممنوع هستند، URI موقت content:// تولید میکند. برای استفاده، باید files-path یا external-files-path را در تنظیمات XML مشخص کنید. افزونههای برنامه در توسعه موبایل در اندروید به عنوان یک مفهوم جداگانه وجود ندارند، اما FileProvider عملکرد آنها را انجام میدهد — قابلیتهای اشتراکگذاری داده را فراتر از یک برنامه گسترش میدهد.
در iOS، نقش اشتراکگذاری فایل توسط File Provider Extension انجام میشود. File Provider Extension فایلهای برنامه را در برنامه Files از طریق NSFileProviderManager منتشر میکند. برخلاف FileProvider، افزونه iOS به یک باینری جداگانه نیاز دارد و در یک فرآیند ایزوله اجرا میشود. File Provider Extension از NSFileProviderItem برای توصیف فایل و NSFileProviderEnumerator برای پیمایش پوشه پشتیبانی میکند. یکپارچهسازیهای سیستمی در برنامههای موبایل از طریق File Provider Extension به کاربر اجازه میدهد فایلهای برنامه را از برنامه Files بدون باز کردن آن مدیریت کند.
class MyFileProviderExtension: NSFileProviderExtension {
override func item(for identifier: NSFileProviderItemIdentifier) throws -> NSFileProviderItem {
return MyFileProviderItem(identifier: identifier)
}
}
مثال یک پیادهسازی حداقلی از File Provider Extension را در Swift نشان میدهد. متد item(for:) یک شی NSFileProviderItem را بر اساس شناسه برمیگرداند — سیستم هنگام نمایش فایلها در برنامه Files آن را فراخوانی میکند.
سوالات متداول
افزونههای برنامه باینریهای جداگانهای هستند که عملکرد برنامه را فراتر از فرآیند آن گسترش میدهند: Today Widget، Share Extension، Action Extension، Keyboard Extension و انواع دیگر که در یک محیط ایزوله اجرا میشوند.
CallKit تماسهای VoIP را در رابط تماس سیستم با نمایش در صفحه قفل شده ادغام میکند. PushKit اعلانهای فشاری پسزمینه را بدون نمایش به کاربر تحویل میدهد — برنامه را برای پردازش داده، مانند اطلاعات تماس ورودی، بیدار میکند.
BroadcastReceiver مؤلفه اندروید است که به پیامهای پخش سیستمی واکنش نشان میدهد: بوت دستگاه (BOOT_COMPLETED)، اتصال شبکه (CONNECTIVITY_ACTION)، تغییر حالت هواپیما و سایر رویدادهای سیستم عامل.
برای ایجاد رابط ویجت از AppWidgetProvider با RemoteViews یا برای رویکرد Kotlin DSL از Glance API (Jetpack) استفاده کنید. ویجت از طریق توصیف XML که اندازه و فرکانس بهروزرسانی را مشخص میکند در مانیفست ثبت میشود.
Content Provider مؤلفه اندروید برای اشتراکگذاری داده بین برنامهها از طریق ContentResolver است. برای دسترسی به مخاطبین، فایلهای رسانه و هر داده ساختاریافته از برنامههای دیگر استفاده میشود.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.