Action Extensionは、コンテキストを切り替えずに他のアプリのコンテンツに対してカスタムアクションを実行するiOS拡張機能です。データを別のアプリに送信するShare Extensionとは異なり、Action Extensionはその場でコンテンツを変換します。テキストの翻訳、画像フィルターの変更、スペルチェック、PDF生成などを行います。Apple(2024)によると、Action ExtensionはShare Extensionに次いで2番目に人気のある拡張タイプで、“生産性”カテゴリの42%のアプリで使用されています。メインアプリを起動せずに即座にアクションを実行できることが、ユーザーにとっての主な利点です。
重要なポイント
Action Extensionは、ホストアプリのコンテキスト内で直接コンテンツに対してアクションを実行できるiOSアプリ拡張機能の一種です。ユーザーがSafariでテキストを選択し、“アクション”をタップして、例えば“スペルチェック”を選択すると、拡張機能がテキストを処理し、ブラウザを離れることなく結果を返します。拡張機能はNSExtensionContextを介して入力データを受け取り、変更されたコンテンツを返すことができます。
Action ExtensionはiOS 8でアプリ拡張機能アーキテクチャの一部として登場しました。その主な特徴は、拡張機能に独自のインターフェースがない(オプション)ことと、ホストアプリのコンテキストで実行されることです。ユーザーは現在の画面を離れる必要がなく、最小限の認知負荷で済みます。Appleによると、Action Extensionはホストアプリのコンテンツを同時に読み取りと変更ができる唯一の拡張タイプです(結果返却付きのNSExtensionContext経由)。
Action Extensionはさまざまなシナリオで使用されます。ブラウザでのテキスト翻訳、WebページからのPDF作成、ギャラリーの写真へのフィルター適用、任意のテキストフィールドでのスペルチェック、URL短縮、テキスト暗号化、ブックマーク追加などです。汎用性の高さから、Action Extensionは“ユーティリティ”カテゴリと“生産性”カテゴリのアプリで人気のツールとなっています。
Action ExtensionとShare Extensionはしばしば混同されますが、その目的は根本的に異なります。Share Extensionはホストアプリからあなたのアプリにコンテンツを送信します。Action Extensionはコンテンツを処理して返します。この違いは、アーキテクチャ、ユーザーエクスペリエンス、Info.plistの設定要件に影響します。
| 特性 | Action Extension | Share Extension |
|---|---|---|
| 目的 | コンテンツの変換 | アプリへのコンテンツ転送 |
| インターフェース | オプション(カスタム) | SLComposeServiceViewController |
| データ返却 | あり(completeRequest経由) | なし |
| コンテキスト | ホストアプリ内に留まる | 拡張機能に切り替わる |
| メニュー位置 | Action Sheet(上部) | Share Sheet(下部) |
| 典型的なアクション | 翻訳、修正、フィルター | 保存、公開 |
Action Extensionは、“共有”ボタンまたは“...”をタップするとアクションメニュー(Action Sheet)に表示されます。iOSは自動的にAction Extensionsをシートの上部(アクション)に、Share Extensionsを下部(アプリ)に配置します。ユーザーシナリオ:テキストを選択 → “アクション”をタップ → あなたのAction Extensionを選択 → アプリを切り替えずに処理結果を受け取る。
Action Extensionは、Xcodeのターゲット、インターフェース表示用のUIViewController(オプション)、データ入出力用のNSExtensionContext、Info.plist設定で構成されます。アーキテクチャはShare Extensionよりもシンプルで、必須のコンポーズインターフェースはなく、拡張機能はUIなしで完全に動作できます。
ターゲット — メインアプリから継承した識別子を持つ個別のバンドル。UIViewController — 進捗、設定、結果を表示するオプションのインターフェース。NSExtensionContext — 入力データ(inputItems)と結果返却用のcompleteRequestメソッドを持つコンテナ。Info.plist — NSExtensionActivationRuleとサポートするコンテンツタイプを指定する属性(NSExtensionAttributes)によるアクティベーション設定。
Action Extensionは入力データをextensionContext?.inputItems(NSExtensionItemの配列)を介して受け取ります。各アイテムにはデータとUTIを持つアタッチメントが含まれます。処理後、拡張機能は出力NSExtensionItemの配列を指定してcompleteRequest(returningItems:)を呼び出します。ホストアプリは処理済みデータを受け取り表示します。非同期モデル:拡張機能は最大30秒間コンテキストを保持して長時間の操作を実行できます。
選択したテキストを翻訳するSwiftでのAction Extensionの作成を見てみましょう。拡張機能はホストアプリからテキストを受け取り、翻訳サーバーに送信して結果を返します。ActionViewControllerは、Xcodeがターゲットを追加するときに作成する基本コントローラです。
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
}
}
}
}
}
}
処理後、拡張機能は結果をホストアプリに返します。出力データを伴うcompleteRequestは、拡張機能がUIを表示せずに処理済みコンテンツを即座に返す代替シナリオです。
// 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はUIありとなしの2つのモードで動作できます。UIなしモードでは、拡張機能は完全にバックグラウンドでアクションを実行し、処理後すぐにcompleteRequestを呼び出します。UIモードでは、拡張機能がコントローラを表示し、ユーザーがアクションを確認した後、completeRequestが結果を送信します。モードの選択は、アクションの複雑さとユーザー入力の必要性に依存します。
loadItem(forTypeIdentifier:)メソッドは非同期で動作します。データは大きくなる可能性があります(画像、動画)。NSItemProviderがストリーミングとキャッシュを管理します。画像にはkUTTypeImage、ファイルにはkUTTypeFileURLを使用します。重要:loadItemはバックグラウンドスレッドで呼び出される可能性があります。DispatchQueue.mainを介してのみUIを更新してください。
Action Extensionは、NSExtensionItemの配列を指定してcompleteRequestを介して処理済みデータを返します。各アイテムは出力データタイプに対応します。ホストアプリは元のコンテンツを処理済みコンテンツに置き換えることができます。たとえば、元の画像をフィルター適用済みの画像に置き換えることができます。NSExtensionItemは入力と同じUTIに加えて、追加のUTI(Webコンテンツ用のpublic.htmlなど)をサポートします。
Action Extensionは、シンプルなユーティリティから複雑なビジネスワークフローまで、数十のシナリオで使用されています。典型的な例には、テキスト、グラフィック、ファイル操作、およびWebコンテンツの統合が含まれます。
テキスト用のAction Extension:翻訳、スペルチェック、文字数カウント、大文字小文字変換、暗号化、テキストからのQRコード生成。ユーザーはテキストフィールドのある任意のアプリ(Safari、Notes、Mail)でテキストを選択し、ワンタップでアクションを実行します。コードのシンタックスハイライト、Markdownフォーマット、URL短縮は、上級ユーザー向けの一般的なAction Extensionの例です。
画像用のAction Extension:フィルター適用、切り抜き、サイズ変更、フォーマット変換(HEICからJPEG)、透かし追加、テキスト認識(OCR)、圧縮。画像処理は高速である必要があります。ユーザーは2〜3秒以内に結果を期待します。負荷の高い操作には、GPU上のCore Imageまたはバックグラウンドキューを使用してください。
URL用のAction Extension:WebページからのPDF作成、Pocket/Pinterestへの保存、サイト速度の確認、ページのアーカイブ、Open Graphメタデータの取得、ページのスクリーンショット生成。PDF生成は最も需要の高いシナリオの1つで、ユーザーはサードパーティサービスを開かずにWebページをPDFに変換します。
よくある質問
Share Extensionはホストアプリからあなたのアプリにコンテンツを送信します。Action Extensionはその場でコンテンツを処理し、結果を返します。Shareは転送、Actionは変換です。この根本的な違いがアーキテクチャとUXを決定します。
いいえ。アクションがユーザー入力を必要としない場合(文字数カウントなど)、拡張機能はバックグラウンドで実行し、completeRequestを介して即座に結果を返すことができます。Info.plistでNSExtensionActivationSupportsWebURLまたはデータタイプに一致する別のUTIを指定する必要があります。
UIActivityViewControllerまたは標準のアクションコントローラをサポートする任意のアプリで表示されます。これにはSafari、写真、ファイル、メモ、メール、および数千のサードパーティアプリが含まれます。Action Extensionは、iOSの標準アクション機構を使用しないアプリでは動作しません。
extensionContext.completeRequest(returningItems:)をNSExtensionItemの配列を指定して呼び出します。各出力アイテムには処理済みデータを持つNSItemProviderが含まれます。ホストアプリはUIActivityViewControllerのデリゲートまたは類似のコールバックで結果を受け取ります。
拡張機能は最大30秒間実行され、その後iOSが強制的に終了します。メインアプリへの直接アクセスはなく、App Groupsを介してのみアクセス可能です。Action Extensionは完了後にバックグラウンドタスクを実行できません。長時間の操作には、次回起動時に通知を伴うバックグラウンドNSURLSessionを使用してください。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。