Action Extension is an iOS extension that performs custom actions on content from other apps without switching context. Unlike Share Extension, which sends data to another app, Action Extension transforms content right in place: translates text, changes image filters, checks spelling, or generates PDF. According to Apple (2024), Action Extension is the second most popular extension type after Share Extension, used in 42% of apps in the "Productivity" category. Instant action without launching the main app is the key advantage for the user.
Key Takeaways
Action Extension is a type of iOS app extension that allows performing actions on content directly within the context of the host app. The user selects text in Safari, taps "Actions" and chooses, for example, "Check Spelling" — the extension processes the text and returns the result without leaving the browser. The extension receives input data via NSExtensionContext and can return modified content back.
Action Extension appeared in iOS 8 as part of the app extensions architecture. Its key feature is that the extension does not have its own interface (optional) and runs in the context of the host app. The user does not leave the current screen, ensuring minimal cognitive friction. According to Apple, Action Extension is the only extension type that can simultaneously read and modify host app content (via NSExtensionContext with result return).
Action Extension is used in various scenarios: translating text in the browser, creating PDF from a web page, applying a filter to a photo in the gallery, checking spelling in any text field, shortening URLs, encrypting text, and adding bookmarks. Versatility makes Action Extension a popular tool for apps in the "Utilities" and "Productivity" categories.
Action Extension and Share Extension are often confused, but their purposes are fundamentally different. Share Extension sends content from the host app to your app; Action Extension processes content and returns it back. The difference affects the architecture, user experience, and Info.plist configuration requirements.
| Characteristic | Action Extension | Share Extension |
|---|---|---|
| Purpose | Content transformation | Content transfer to app |
| Interface | Optional (custom) | SLComposeServiceViewController |
| Data return | Yes, via completeRequest | No |
| Context | Stays in host app | Switches to extension |
| Menu position | Action Sheet (top part) | Share Sheet (bottom part) |
| Typical action | Translation, correction, filter | Saving, publishing |
Action Extension appears in the action menu (Action Sheet) when tapping the "Share" button or "...". iOS automatically places Action Extensions in the top part of the sheet (actions) and Share Extensions in the bottom part (apps). User scenario: selected text → tapped "Actions" → chose your Action Extension → received processed result without switching apps.
Action Extension consists of a target in Xcode, a UIViewController for displaying the interface (optional), NSExtensionContext for data input/output, and Info.plist configuration. The architecture is simpler than Share Extension: there is no mandatory compose interface, and the extension can work entirely without a UI.
Target — a separate bundle with an identifier inherited from the main app. UIViewController — optional interface for displaying progress, settings, or results. NSExtensionContext — a container with input data (inputItems) and the completeRequest method for returning results. Info.plist — activation configuration via NSExtensionActivationRule and attributes (NSExtensionAttributes) for specifying supported content types.
Action Extension receives input data via extensionContext?.inputItems — an array of NSExtensionItem. Each item contains attachments with data and UTIs. After processing, the extension calls completeRequest(returningItems:) with an array of output NSExtensionItems. The host app receives the processed data and displays it. Async model: the extension can perform long-running operations, holding the context for up to 30 seconds.
Let's look at creating an Action Extension in Swift for translating selected text. The extension receives text from the host app, sends it to a translation server, and returns the result. ActionViewController is the base controller created by Xcode when adding a target.
import UIKit
import MobileCoreServices
class ActionViewController: UIViewController {
@IBOutlet var resultLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
extractTextAndTranslate()
}
func extractTextAndTranslate() {
guard let item = extensionContext?.inputItems.first
as? NSExtensionItem
else { return }
for attachment in item.attachments ?? [] {
attachment.loadItem(
forTypeIdentifier: kUTTypePlainText as String
) { [weak self] (text, error) in
guard let inputText = text as? String else { return }
TranslationService().translate(inputText, from: "en", to: "ru") {
translated in
DispatchQueue.main.async {
self?.resultLabel?.text = translated
}
}
}
}
}
}
After processing, the extension returns the result to the host app. completeRequest with output data is an alternative scenario where the extension does not show a UI but immediately returns the processed content.
// Returning processed text to host app
let resultItem = NSExtensionItem()
let resultData = translated.data(using: .utf8)!
let attachment = NSItemProvider(
item: resultData,
typeIdentifier: kUTTypePlainText as String
)
resultItem.attachments = [attachment]
extensionContext?.completeRequest(
returningItems: [resultItem], completionHandler: nil
)
Action Extension can work in two modes: with UI and without UI. In the no-UI mode, the extension performs the action entirely in the background and calls completeRequest immediately after processing. In the UI mode, the extension shows a controller, the user confirms the action, and only then completeRequest sends the result. Mode selection depends on the complexity of the action and the need for user input.
The loadItem(forTypeIdentifier:) method works asynchronously — data can be large (images, videos). NSItemProvider manages streaming and caching. For images use kUTTypeImage, for files use kUTTypeFileURL. Important: loadItem may be called on a background thread — update UI only via DispatchQueue.main.
Action Extension returns processed data via completeRequest with an array of NSExtensionItem. Each item corresponds to the output data type. The host app can replace the original content with the processed one — for example, replace the original image with a filtered one. NSExtensionItem supports the same UTIs as input, plus additional ones (e.g., public.html for web content).
Action Extension is used in dozens of scenarios — from simple utilities to complex business workflows. Classic examples cover text, graphic, and file operations, as well as web content integration.
Action Extension for text: translation, spell checking, character count, case conversion, encryption, QR code generation from text. The user selects text in any app with a text field (Safari, Notes, Mail) and performs the action with one tap. Syntax highlighting of code, Markdown formatting, and URL shortening are popular Action Extension examples for advanced users.
For images, Action Extension offers: applying filters, cropping, resizing, format conversion (HEIC to JPEG), watermarking, text recognition (OCR), and compression. Image processing should be fast — the user expects a result within 2–3 seconds. For heavy operations use Core Image on GPU or background queues.
Action Extension for URLs: creating PDF from a web page, saving to Pocket/Pinterest, checking site speed, archiving a page, retrieving Open Graph metadata, generating a page screenshot. PDF generation is one of the most demanded scenarios: the user converts a web page to PDF without opening third-party services.
Frequently Asked Questions
Share Extension sends content from the host app to your app. Action Extension processes content in place and returns the result back. Share — transfer, Action — transformation. This fundamental difference determines the architecture and UX.
Yes. If the action does not require user input (e.g., character count), the extension can perform it in the background and immediately return the result via completeRequest. In Info.plist you need to specify NSExtensionActivationSupportsWebURL or another UTI matching the data type.
In any apps that support UIActivityViewController or standard action controllers. These include Safari, Photos, Files, Notes, Mail, and thousands of third-party apps. Action Extension does not work in apps that do not use standard iOS action mechanisms.
Via extensionContext.completeRequest(returningItems:) with an array of NSExtensionItem. Each output item contains an NSItemProvider with the processed data. The host app receives the result in the UIActivityViewController delegate or a similar callback.
The extension runs for up to 30 seconds, after which iOS forcefully terminates it. There is no direct access to the main app — only through App Groups. Action Extension cannot perform background tasks after completion. For long operations, use background NSURLSession with a notification on the next launch.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also