Share Extension — to rozszerzenie iOS, które dodaje twoją aplikację do systemowego menu “Udostępnij” (Share Sheet). Użytkownik może wysłać treści z Safari, Zdjęć, Plików lub dowolnej innej aplikacji bezpośrednio do twojej — bez kopiowania i przełączania między oknami. Według danych Apple (2024), aplikacje z Share Extension otrzymują 35% więcej treści od użytkowników niż aplikacje bez możliwości udostępniania. Rozszerzenie przetwarza tekst, obrazy, wideo, URL i pliki przez ujednolicony interfejs NSExtensionItem.
Najważniejsze
Share Extension — to typ rozszerzenia iOS app extension, które pojawia się w systemowym menu “Udostępnij” po zaznaczeniu treści w dowolnej aplikacji. Użytkownik zaznacza tekst w Safari, naciska “Udostępnij” i widzi twoją aplikację na liście dostępnych działań. Po wybraniu treść jest przekazywana do rozszerzenia w celu przetworzenia: zapisania, opublikowania, wysłania lub przekształcenia.
W przeciwieństwie do Action Extension, Share Extension specjalizuje się w otrzymywaniu treści z zewnętrznych aplikacji. Action Extension, odwrotnie, wysyła dane z twojej aplikacji na zewnątrz. Share Extension to punkt wejścia treści użytkownika, kluczowy element pozyskiwania użytkowników: użytkownik wypróbowuje aplikację przez Share Extension, nie instalując jej w pełni. App Store zabrania aplikacjom, których jedyną funkcją jest wyświetlanie reklam przez Share Extension (App Store Review Guideline 4.2).
Share Extension obniża próg wejścia: użytkownik wysyła treść do twojej aplikacji ze znanego kontekstu — przeglądarki, galerii, menedżera plików. Według danych Branch (2024), aplikacje z Share Extension wykazują 28% wyższy retention w 7. dniu. Dodatkowy efekt — wiralność: za każdym razem, gdy użytkownik widzi twoją aplikację w Share Sheet, następuje pasywny branding bez kosztów reklamy.
Mechanizm Share Extension opiera się na przesyłaniu treści przez systemowe kontenery NSExtensionItem. Aplikacja gospodarza (Safari, Zdjęcia) pakuje wybraną treść do NSExtensionItem z określeniem typu (public.image, public.url, public.plain-text). System przekazuje ten kontener do rozszerzenia, które wyodrębnia dane przez extensionContext.inputItems.
Share Extension uruchamia się w osobnym procesie z ograniczonym czasem wykonania — około 30 sekund na przetworzenie. Rozszerzenie nie powinno wykonywać długotrwałych operacji synchronicznie. Do ładowania dużych plików używaj NSURLSession z konfiguracją tła. SLComposeServiceViewController — klasa bazowa dla Share Extension z podglądem treści i przyciskiem wysyłania.
iOS używa Uniform Type Identifiers (UTI) do określania typu przesyłanej treści. Główne UTI dla Share Extension: public.image (zdjęcia, zrzuty ekranu), public.url (linki), public.plain-text (tekst), public.video (pliki wideo) i public.file-url (pliki). Rozszerzenie rejestruje obsługiwane UTI w Info.plist przez klucz NSExtensionActivationRule.
Share Extension składa się z trzech komponentów: docelowego targetu w Xcode, SLComposeServiceViewController i konfiguracji Info.plist. Architektura określa, które typy treści są przetwarzane, jak wyświetlany jest interfejs i gdzie zapisywane są dane.
| Komponent | Przeznaczenie | Cechy |
|---|---|---|
| Target | Target rozszerzenia w Xcode | Oddzielny bundle z identyfikatorem |
| ViewController | Interfejs i logika przetwarzania | SLComposeServiceViewController lub własny |
| Info.plist | Konfiguracja aktywacji i UTI | NSExtensionActivationRule z predykatami |
| App Groups | Wspólne repozytorium z aplikacją | UserDefaults suite do przesyłania danych |
Kluczowy element konfiguracji Share Extension — reguła aktywacji. Określa ona, w jakich warunkach rozszerzenie pojawia się w Share Sheet. Reguła jest określana w Info.plist jako słownik z ograniczeniami: maksymalna liczba obrazów, minimalna długość tekstu, obowiązkowa obecność URL. Standardowa reguła aktywuje rozszerzenie dla jednego dowolnego typu treści.
// Info.plist — NSExtensionActivationRule dla Share Extension
<key>NSExtensionActivationRule</key>
<dict>
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
<integer>5</integer>
<key>NSExtensionActivationSupportsText</key>
<true/>
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
<integer>1</integer>
</dict>
Rozważmy praktyczny przykład tworzenia Share Extension w Swift dla aplikacji do zakładek. Rozszerzenie otrzymuje URL z Safari, wyświetla interfejs z podglądem i zapisuje link w App Group. SLComposeServiceViewController zapewnia gotowy interfejs z polem tekstowym i przyciskiem 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)
}
}
}
}
Po wysłaniu treści rozszerzenie kończy działanie wywołaniem completeRequest — to obowiązkowy krok, bez niego system nie zwolni procesu rozszerzenia. Ważne: Share Extension działa w ograniczonym środowisku z ograniczonym dostępem do sieci i systemu plików — używaj sesji tła do ładowania treści.
Share Extension musi poprawnie przetwarzać różne typy danych wejściowych: tekst, obrazy, wideo, URL i pliki. Dla każdego typu używany jest własny UTI i własna metoda wyodrębniania danych. Uniwersalne przetwarzanie — przez pętlę po attachment.attachments ze sprawdzeniem hasItemConformingToTypeIdentifier.
Obrazy są przesyłane jako public.image z możliwością pobrania przez UIImage lub Data. Dla dużych obrazów używaj jpegData(compressionQuality:) przed zapisaniem. Share Extension nie powinien modyfikować oryginalnego obrazu bez wyraźnej zgody użytkownika. Zaleca się zapisywanie oryginału w App Group i tworzenie podglądu do wyświetlenia w interfejsie.
Safari i inne przeglądarki przesyłają URL jako public.url, a zaznaczony tekst jako public.plain-text. Jeden NSExtensionItem może zawierać oba typy jednocześnie — URL strony i zaznaczony na niej tekst. Share Extension powinien sprawdzić wszystkie attachment-y i wyodrębnić istotne dane. Scenariusz kombinowany: zapisać URL jako zakładkę, a tekst jako notatkę do niej.
Share Extension i główna aplikacja działają w różnych procesach i nie mają wspólnego dostępu do systemu plików. Do wymiany danych używany jest mechanizm App Groups: wspólny kontener z identyfikatorem group.*. Po zapisaniu danych w App Group rozszerzenie powiadamia aplikację przez CFNotificationCenter lub Darwin Notify.
App Groups włącza się w Capabilities targetu: wybierz “App Groups” i dodaj identyfikator (np. group.com.example.myapp). Oba targety — główna aplikacja i rozszerzenie — muszą mieć dostęp do tej samej grupy. UserDefaults suite pozwala czytać i zapisywać dane we wspólnym repozytorium przy minimalnych nakładach.
// Zapisywanie danych do App Group z 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()
Często zadawane pytania
Share Extension przyjmuje treści z innych aplikacji do twojej. Action Extension, odwrotnie, wykonuje działanie na treści wewnątrz aplikacji gospodarza — tłumaczenie tekstu, modyfikację obrazu. Share Extension — otrzymywanie, Action Extension — transformacja.
To zależy od typu treści twojej aplikacji. Dla zakładek — public.url. Dla edytora zdjęć — public.image. Dla notatek — public.plain-text. Dla wielu typów używaj NSExtensionActivationRule z kombinacją predykatów AND/OR.
Częstą przyczyną jest nieprawidłowy NSExtensionActivationRule lub niezgodność UTI. Sprawdź w Info.plist: reguła aktywacji musi odpowiadać testowanemu typowi treści. Upewnij się również, że rozszerzenie jest włączone w Ustawienia → twoja aplikacja → Siri i wyszukiwanie. Xcode clean build często rozwiązuje problem.
System przydziela około 30 sekund na wykonanie. Po tym czasie iOS wymusza zakończenie procesu rozszerzenia. Do długotrwałych operacji używaj tła NSURLSession z przetwarzaniem wyniku przy następnym uruchomieniu aplikacji.
Tak, zamiast SLComposeServiceViewController można użyć zwykłego UIViewController. W takim przypadku w pełni kontrolujesz interfejs. Jednak przyciski wysyłania i anulowania trzeba zaimplementować samodzielnie. Własny interfejs jest zalecany dla niestandardowych scenariuszy przetwarzania treści.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również