Action Extension是一种iOS扩展,无需切换上下文即可对其他应用的内容执行自定义操作。与将数据发送到其他应用的Share Extension不同,Action Extension直接在原地转换内容:翻译文本、更改图像滤镜、检查拼写或生成PDF。根据Apple(2024)的数据,Action Extension是仅次于Share Extension的第二大流行扩展类型,被42%的“生产力”类别应用所使用。无需启动主应用的即时操作——对用户来说是一个关键优势。
要点
Action Extension是一种iOS应用扩展类型,允许您直接在宿主应用的上下文中对内容执行操作。用户在Safari中选择文本,点击“操作”并选择例如“检查拼写”——扩展程序处理文本并返回结果,无需离开浏览器。扩展通过NSExtensionContext接收输入数据,并可以返回修改后的内容。
Action Extension在iOS 8中作为应用扩展架构的一部分出现。其关键特性是扩展没有自己的界面(可选)并且在宿主应用的上下文中运行。用户不会离开当前屏幕,从而确保最小的认知中断。据Apple称,Action Extension是唯一可以同时读取和修改宿主应用内容的扩展类型(通过NSExtensionContext返回结果)。
Action Extension用于各种场景:在浏览器中翻译文本、从网页创建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放在sheet的顶部(操作),而Share Extensions放在底部(应用)。用户场景:选择了文本→点击了“操作”→选择了您的Action Extension→无需切换应用即可收到处理后的结果。
Action Extension由Xcode中的target、用于显示界面的UIViewController(可选)、用于数据输入输出的NSExtensionContext和Info.plist配置组成。架构比Share Extension更简单:没有强制性的组合界面,扩展可以完全在没有UI的情况下工作。
Target——一个独立的bundle,带有从主应用继承的标识符。UIViewController——用于显示进度、设置或结果的可选界面。NSExtensionContext——包含输入数据(inputItems)和用于返回结果的completeRequest方法的容器。Info.plist——通过NSExtensionActivationRule进行激活配置,以及用于指定支持的内容类型的属性(NSExtensionAttributes)。
Action Extension通过extensionContext?.inputItems接收输入数据——NSExtensionItem数组。每个元素包含带有数据和UTI的附件。处理后,扩展调用completeRequest(returningItems:),带有一个输出NSExtensionItem数组。宿主应用接收处理后的数据并显示。异步模型:扩展可以执行长时间的操作,将上下文保持最多30秒。
让我们看看在Swift中创建一个用于翻译所选文本的Action Extension。扩展从宿主应用接收文本,将其发送到翻译服务器,然后返回结果。ActionViewController——Xcode在添加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
}
}
}
}
}
}
处理后,扩展将结果返回到宿主应用。completeRequest带输出数据——替代场景,当扩展不显示UI而直接返回处理后的内容时。
// 将处理后的文本返回到宿主应用
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和无UI。在无UI模式下,扩展完全在后台执行操作,并在处理后立即调用completeRequest。在有UI模式下,扩展显示一个控制器,用户确认操作,然后completeRequest才发送结果。模式选择取决于操作的复杂性和用户输入的需要。
loadItem(forTypeIdentifier:)方法异步工作——数据可能很大(图像、视频)。NSItemProvider管理流式加载和缓存。对于图像使用kUTTypeImage,对于文件使用kUTTypeFileURL。重要:loadItem可能在后台线程上调用——只能通过DispatchQueue.main更新UI。
Action Extension通过completeRequest返回处理后的数据,带有一个NSExtensionItem数组。每个元素对应一个输出数据类型。宿主应用可以用处理后的内容替换原始内容——例如,将原始图像替换为经过滤镜处理的图像。NSExtensionItem支持与输入相同的UTI,以及附加的UTI(例如,用于网页内容的public.html)。
Action Extension应用于数十种场景——从简单的工具到复杂的业务流程。经典示例包括文本、图形和文件操作,以及与网页内容的集成。
Action Extension用于文本:翻译、拼写检查、字符计数、大小写更改、加密、从文本创建二维码。用户在任何带有文本字段的应用(Safari、备忘录、邮件)中选择文本,然后一键执行操作。代码语法高亮、Markdown格式化和URL缩短——高级用户的流行Action Extension示例。
对于图像,Action Extension提供:应用滤镜、裁剪、调整大小、格式转换(HEIC转JPEG)、添加水印、文本识别(OCR)和压缩。图像处理必须快速——用户期望在2-3秒内得到结果。对于繁重操作,使用GPU上的Core Image或后台队列。
Action Extension用于URL:从网页创建PDF、保存到Pocket/Pinterest、检查网站速度、归档页面、获取Open Graph元数据、生成页面截图。PDF生成——最受欢迎的场景之一:用户将网页转换为PDF,无需打开第三方服务。
常见问题
Share Extension将内容从宿主应用发送到您的应用。Action Extension在原地处理内容并返回结果。Share——传输,Action——转换。这是决定架构和用户体验的根本区别。
可以。如果操作不需要用户输入(例如字符计数),扩展可以在后台执行它并立即通过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应用程序。我们将为您提供咨询并提出最佳解决方案。