Share Extension — это расширение iOS, которое добавляет ваше приложение в системное меню "Поделиться" (Share Sheet). Пользователь может отправить контент из Safari, Фото, Файлов или любого другого приложения напрямую в ваше — без копирования и переключения между окнами. По данным Apple (2024), приложения с Share Extension получают на 35% больше пользовательского контента, чем приложения без возможности шеринга. Расширение обрабатывает текст, изображения, видео, URL и файлы через унифицированный интерфейс NSExtensionItem.
Главное
Share Extension — это тип расширения iOS app extension, которое появляется в системном меню "Поделиться" при выборе контента в любом приложении. Пользователь выделяет текст в Safari, нажимает "Поделиться" и видит ваше приложение в списке доступных действий. После выбора контент передаётся в расширение для обработки: сохранения, публикации, отправки или преобразования.
В отличие от Action Extension, Share Extension специализируется на получении контента из внешних приложений. Action Extension, наоборот, отправляет данные из вашего приложения вовне. Share Extension — точка входа пользовательского контента, ключевой элемент user acquisition: пользователь пробует приложение через Share Extension, не устанавливая его полностью. App Store запрещает приложениям, единственная функция которых — показывать рекламу через Share Extension (App Store Review Guideline 4.2).
Share Extension снижает барьер входа: пользователь отправляет контент в ваше приложение из привычного контекста — браузера, галереи, файлового менеджера. По данным Branch (2024), приложения с Share Extension показывают на 28% выше retention на 7-й день. Дополнительный эффект — виральность: каждый раз, когда пользователь видит ваше приложение в Share Sheet, происходит пассивный брендинг без затрат на рекламу.
Механизм Share Extension основан на передаче контента через системные контейнеры NSExtensionItem. Хост-приложение (Safari, Фото) упаковывает выбранный контент в NSExtensionItem с указанием типа (public.image, public.url, public.plain-text). Система передаёт этот контейнер в расширение, которое извлекает данные через extensionContext.inputItems.
Share Extension запускается в отдельном процессе с ограниченным временем выполнения — около 30 секунд на обработку. Расширение не должно выполнять длительных операций синхронно. Для загрузки больших файлов используйте NSURLSession с фоновой конфигурацией. SLComposeServiceViewController — базовый класс для Share Extension с предварительным просмотром контента и кнопкой отправки.
iOS использует Uniform Type Identifiers (UTI) для определения типа передаваемого контента. Основные UTI для Share Extension: public.image (фото, скриншоты), public.url (ссылки), public.plain-text (текст), public.video (видеофайлы) и public.file-url (файлы). Расширение регистрирует поддерживаемые UTI в Info.plist через ключ NSExtensionActivationRule.
Share Extension состоит из трёх компонентов: целевой таргет в Xcode, SLComposeServiceViewController и конфигурации Info.plist. Архитектура определяет, какие типы контента обрабатываются, как отображается интерфейс и куда сохраняются данные.
| Компонент | Назначение | Особенности |
|---|---|---|
| Target | Таргет расширения в Xcode | Отдельный bundle с идентификатором |
| ViewController | Интерфейс и логика обработки | SLComposeServiceViewController или кастомный |
| Info.plist | Конфигурация активации и UTI | NSExtensionActivationRule с предикатами |
| App Groups | Общее хранилище с приложением | UserDefaults suite для передачи данных |
Ключевой элемент конфигурации Share Extension — правило активации. Оно определяет, при каких условиях расширение появляется в Share Sheet. Правило задаётся в Info.plist как словарь с ограничениями: максимальное количество изображений, минимальная длина текста, обязательное наличие URL. Стандартное правило активирует расширение для одного любого типа контента.
// Info.plist — NSExtensionActivationRule for Share Extension
<key>NSExtensionActivationRule</key>
<dict>
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
<integer>5</integer>
<key>NSExtensionActivationSupportsText</key>
<true/>
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
<integer>1</integer>
</dict>
Рассмотрим практический пример создания Share Extension на Swift для приложения-закладок. Расширение получает URL из Safari, отображает интерфейс с предварительным просмотром и сохраняет ссылку в App Group. SLComposeServiceViewController предоставляет готовый UI с текстовым полем и кнопкой Post.
import Social
import MobileCoreServices
class ShareViewController: SLComposeServiceViewController {
override func isContentValid() -> Bool {
return !(contentText?.isEmpty() ?? true)
}
override func didSelectPost() {
guard let item = extensionContext?.inputItems.first as? NSExtensionItem
else { return }
for attachment in item.attachments ?? [] {
attachment.loadItem(forTypeIdentifier: kUTTypeURL as String) {
[weak self] (item, error) in
if let url = item as? URL {
BookmarkService().save(url, title: self?.contentText)
}
self?.extensionContext?.completeRequest(
returningItems: [], completionHandler: nil)
}
}
}
}
После отправки контента расширение завершает работу вызовом completeRequest — это обязательный шаг, без него система не освободит процесс расширения. Важно: Share Extension работает в лимитированном окружении с ограниченным доступом к сети и файловой системе — используйте фоновые сессии для загрузки контента.
Share Extension должен корректно обрабатывать разные типы входных данных: текст, изображения, видео, URL и файлы. Для каждого типа используется свой UTI и свой метод извлечения данных. Универсальная обработка — через цикл по attachment.attachments с проверкой hasItemConformingToTypeIdentifier.
Изображения передаются как public.image с возможностью получения через UIImage или Data. Для больших изображений используйте jpegData(compressionQuality:) перед сохранением. Share Extension не должен модифицировать оригинальное изображение без явного разрешения пользователя. Рекомендуется сохранять оригинал в App Group и создавать превью для отображения в интерфейсе.
Safari и другие браузеры передают URL как public.url, а выделенный текст — как public.plain-text. Один NSExtensionItem может содержать оба типа одновременно — URL страницы и выделенный на ней текст. Share Extension должен проверить все attachment-ы и извлечь релевантные данные. Комбинированный сценарий: сохранить URL как закладку, а текст — как заметку к ней.
Share Extension и основное приложение работают в разных процессах и не имеют общего доступа к файловой системе. Для обмена данными используется механизм App Groups: общий контейнер с идентификатором group.*. После сохранения данных в App Group расширение уведомляет приложение через CFNotificationCenter или Darwin Notify.
App Groups включаются в Capabilities таргета: выберите "App Groups" и добавьте идентификатор (например, group.com.example.myapp). Оба таргета — основное приложение и расширение — должны иметь доступ к одной группе. UserDefaults suite позволяет читать и записывать данные в общее хранилище с минимальными накладными расходами.
// Saving data to App Group from Share Extension
let sharedDefaults = UserDefaults(suiteName: "group.com.example.myapp")
let bookmark: [String: Any] = [
"url": url.absoluteString,
"title": contentText ?? "",
"date": Date().timeIntervalSince1970
]
sharedDefaults?.set(bookmark, forKey: "bookmark_\(Date().timeIntervalSince1970)")
sharedDefaults?.synchronize()
Часто задаваемые вопросы
Share Extension принимает контент из других приложений в ваше. Action Extension, наоборот, выполняет действие с контентом внутри хост-приложения — перевод текста, изменение изображения. Share Extension — получение, Action Extension — трансформация.
Зависит от типа контента вашего приложения. Для закладок — public.url. Для фоторедактора — public.image. Для заметок — public.plain-text. Для нескольких типов используйте NSExtensionActivationRule с комбинацией предикатов AND/OR.
Частая причина — некорректный NSExtensionActivationRule или несовпадение UTI. Проверьте в Info.plist: activation rule должен соответствовать тестируемому типу контента. Также убедитесь, что расширение включено в Settings → ваше приложение → Siri & Search. Xcode clean build часто решает проблему.
Система выделяет около 30 секунд на выполнение. После этого iOS принудительно завершает процесс расширения. Для длительных операций используйте фоновую NSURLSession с обработкой результата при следующем запуске приложения.
Да, вместо SLComposeServiceViewController можно использовать обычный UIViewController. В этом случае вы полностью контролируете интерфейс. Однако кнопки отправки и отмены нужно реализовать самостоятельно. Кастомный UI рекомендуется для нестандартных сценариев обработки контента.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также