App Extensions — это отдельные исполняемые модули, расширяющие возможности мобильного приложения за пределы его основного интерфейса: Today Widget на домашнем экране, обработка VoIP-звонков через CallKit и реакция на системные события через BroadcastReceiver. Системные интеграции позволяют приложению взаимодействовать с операционной системой на глубоком уровне, открывая функции, недоступные обычным экранам. По данным Apple Developer Documentation, каждое расширение работает в изолированном процессе и управляется системой независимо от основного приложения. App Extensions в мобильном приложении позволяют реализовать функции, недоступные в основном процессе.
Главное
App Extensions на iOS появились в iOS 8 и стали фундаментом для системных интеграций в мобильной разработке. Это отдельные бинарники, упакованные вместе с основным приложением, но запускаемые в изолированном процессе. Каждое расширение имеет собственный Info.plist и точку входа, заданную через NSExtensionPrincipalClass. Система управляет жизненным циклом App Extensions — они не могут оставаться в фоне после завершения задачи.
WidgetKit (iOS 14+) — современный фреймворк для создания виджетов на домашнем экране. WidgetKit использует SwiftUI для описания интерфейса и TimelineProvider для определения расписания обновлений. Виджеты бывают трёх размеров: small (2×2 ячейки), medium (4×2) и large (4×4). Старый Today Widget на UICollectionViewController поддерживается, но Apple рекомендует мигрировать на WidgetKit. App Extensions на WidgetKit не поддерживают анимацию, клавиатурный ввод и жесты — это статичные или псевдоанимированные элементы с периодическим обновлением.
Share Extension позволяет отправлять контент из любого приложения в ваше через системный лист «Поделиться». Share Extension получает данные через NSExtensionItem и использует SLComposeServiceViewController для UI. Action Extension обрабатывает контент на месте — например, переводит текст в браузере без перехода в другое приложение. Оба типа должны завершить работу за ограниченное время, иначе система «убивает» расширение. Это важное ограничение App Extensions в мобильном приложении — фоновые задачи недоступны на уровне расширений.
Системные интеграции на iOS выходят далеко за рамки виджетов: CallKit, PushKit и SiriKit позволяют мобильному приложению работать на системном уровне. Эти фреймворки требуют специальных entitlements, но дают пользователю бесшовный опыт — звонки через CallKit выглядят как обычные телефонные, а Siri обрабатывает запросы без открытия приложения.
CallKit интегрирует звонки сторонних приложений в системный экран вызова, включая заблокированный экран. Провайдер CXProvider регистрирует приложение как VoIP-сервис, а CXCallController управляет звонками. CallKit автоматически блокирует дублирующие вызовы и поддерживает Call Directory Extension для блокировки нежелательных номеров. Системные интеграции в мобильной разработке с CallKit критичны для приложений голосовой связи — WhatsApp, Skype и Zoom используют его для отображения входящих вызовов.
PushKit доставляет push-уведомления напрямую в мобильное приложение без показа пользователю. PushKit пробуждает приложение из «убитого» состояния и передаёт данные через делегат PKPushRegistryDelegate. Это основной механизм для VoIP-приложений: PushKit доставляет информацию о звонке, а CallKit отображает её. PushKit имеет более высокий приоритет доставки, чем обычные push-уведомления, и не требует показа баннера. App Extensions в мобильных приложениях часто комбинируют PushKit с CallKit для организации голосовой связи.
SiriKit позволяет обрабатывать запросы через Siri и приложение «Команды». Intents Extension — отдельный App Extension, который регистрирует поддерживаемые интенты и обрабатывает их. SiriKit поддерживает 20+ доменов: звонки, сообщения, платежи, заметки, тренировки. Shortcuts позволяют пользователю создавать автоматизации — например, «Отправить сообщение в WhatsApp через Siri». Системные интеграции с SiriKit и Shortcuts повышают вовлечённость, так как пользователь выполняет действия без открытия приложения.
BroadcastReceiver — компонент Android, который реагирует на системные широковещательные сообщения. В отличие от iOS App Extensions, BroadcastReceiver не требует отдельного бинарника — достаточно зарегистрировать ресивер в манифесте или в коде через Context.registerReceiver. Системные интеграции на Android часто начинаются с BroadcastReceiver: от запуска сервиса при загрузке устройства до реакции на подключение к сети.
IntentFilter связывает BroadcastReceiver с конкретным системным событием. Типичные события: BOOT_COMPLETED (загрузка устройства), CONNECTIVITY_ACTION (изменение сети), BATTERY_LOW (низкий заряд), TIME_SET (изменение времени). Ресивер регистрируется в AndroidManifest.xml или через Context.registerReceiver для динамической регистрации. Динамическая регистрация предпочтительнее — она не требует разрешений в манифесте и действует только при активном приложении. App Extensions на Android не существуют как концепция, но 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 используется для отложенного выполнения задачи после загрузки устройства — это стандартный подход для Android-приложений.
App Widget Provider на Android — аналог iOS App Extensions в контексте виджетов: это компонент, который отображает интерактивный контент на домашнем экране. В отличие от WidgetKit, Android-виджеты могут принимать ввод пользователя — нажатия, переключения и жесты. App Widget Provider регистрируется в манифесте через XML-описание размера и частоты обновления.
RemoteViews описывает интерфейс виджета через XML-разметку и поддерживает только ограниченный набор View. RemoteViews не позволяет использовать кастомные View — только стандартные компоненты: TextView, ImageView, Button, ProgressBar. AppWidgetProvider — базовый класс, который обрабатывает обновления, включение и удаление виджета. Метод onUpdate вызывается по таймеру через updatePeriodMillis или через WorkManager для точного контроля. Системные интеграции с виджетами на Android требуют осторожности — слишком частое обновление расходует батарею.
Glance API — Jetpack-библиотека для создания виджетов на Kotlin DSL вместо XML. Glance API компилируется в RemoteViews и поддерживает Compose-подобный синтаксис: GlanceComposable, Column, Row, Text. Библиотека решает проблему сложного XML-кода и позволяет тестировать виджеты через JUnit. Glance API пока не поддерживает все возможности RemoteViews — для сложных интерактивных виджетов лучше использовать классический подход. App Extensions в мобильной разработке на Android эволюционируют в сторону Glance API, упрощая создание и поддержку виджетов.
Content Provider — компонент Android для обмена структурированными данными между приложениями через единый интерфейс ContentResolver. В отличие от iOS App Extensions, Content Provider не создаёт отдельный процесс — данные запрашиваются синхронно в контексте вызывающего приложения. Content Provider лежит в основе системных интеграций на Android: контакты, медиафайлы, календарь и стандартные приложения используют его для публикации данных.
FileProvider — подкласс ContentProvider для безопасной передачи файлов между приложениями. FileProvider генерирует временные content:// URI вместо прямых file:// путей, которые запрещены на Android 7+. Для использования нужно указать files-path или external-files-path в XML-конфигурации. App Extensions в мобильной разработке на Android не существуют как отдельная концепция, но FileProvider выполняет их функцию — расширяет возможности обмена данными за пределы одного приложения.
На iOS роль обмена файлами выполняет File Provider Extension. File Provider Extension публикует файлы приложения в Files App через NSFileProviderManager. В отличие от FileProvider, iOS-расширение требует отдельного бинарника и работает в изолированном процессе. File Provider Extension поддерживает NSFileProviderItem для описания файлов и NSFileProviderEnumerator для навигации по папкам. Системные интеграции в мобильных приложениях через File Provider Extension позволяют пользователю управлять файлами приложения из Files App без его открытия.
class MyFileProviderExtension: NSFileProviderExtension {
override func item(for identifier: NSFileProviderItemIdentifier) throws -> NSFileProviderItem {
return MyFileProviderItem(identifier: identifier)
}
}
Пример показывает минимальную реализацию File Provider Extension на Swift. Метод item(for:) возвращает объект NSFileProviderItem по идентификатору — система вызывает его при отображении файлов в Files App.
Часто задаваемые вопросы
App Extensions — это отдельные бинарники, расширяющие функциональность приложения за пределы его процесса: Today Widget, Share Extension, Action Extension, Keyboard Extension и другие типы, работающие в изолированном окружении.
CallKit интегрирует VoIP-звонки в системный интерфейс вызова с отображением на заблокированном экране. PushKit доставляет фоновые push-уведомления без показа пользователю — он пробуждает приложение для обработки данных, например, информации о входящем звонке.
BroadcastReceiver — компонент Android, который реагирует на системные широковещательные сообщения: загрузку устройства (BOOT_COMPLETED), подключение к сети (CONNECTIVITY_ACTION), изменение режима полёта и другие события ОС.
Используйте AppWidgetProvider с RemoteViews для создания интерфейса виджета или Glance API (Jetpack) для Kotlin DSL-подхода. Виджет регистрируется в манифесте через XML-описание с указанием размера и частоты обновления.
Content Provider — компонент Android для обмена данными между приложениями через ContentResolver. Он используется для доступа к контактам, медиафайлам и любым структурированным данным из других приложений.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.