如何在iOS Safari App Extension中获取活跃标签页?为何SFSafariApplication未被识别?
iOS Safari App Extension 问题解决方案
一、获取当前活跃页面的完整数据
在iOS的Safari App Extension中,获取当前页面数据需要通过内容脚本(Content Script) + 后台脚本(Background Script) + App端Handler的协作实现,具体步骤如下:
- 配置内容脚本注入
在Info.plist的SFSafariContentScript数组中添加注入脚本,指定匹配的URL范围:
<key>SFSafariContentScript</key> <array> <dict> <key>Script</key> <string>content.js</string> <key>RunAt</key> <string>DocumentEnd</string> <key>Matches</key> <array> <string>*://*</string> </array> </dict> </array>
- 编写内容脚本获取页面数据
在content.js中抓取页面URL、标题、完整HTML等数据,通过browser.runtime.sendMessage发送到后台脚本:
// content.js const pageData = { url: window.location.href, title: document.title, html: document.documentElement.outerHTML, // 可按需添加其他数据,如特定DOM元素内容 }; browser.runtime.sendMessage({ type: "pageData", data: pageData }) .catch(err => console.error("发送数据失败:", err));
- 后台脚本转发数据到App端
在background.js中接收内容脚本消息,通过browser.runtime.sendNativeMessage传递给App的SafariWebExtensionHandler:
// background.js browser.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.type === "pageData") { browser.runtime.sendNativeMessage("com.yourteam.yourapp", message) .catch(err => console.error("发送到App失败:", err)); } return true; // 保持消息通道开放(支持异步响应) });
- App端Handler接收并处理数据
在SafariWebExtensionHandler.swift中实现messageReceived方法,处理来自后台的页面数据:
import SafariServices class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling { func beginRequest(with context: NSExtensionContext) {} func messageReceived(withName messageName: String, from page: SFSafariPage, userInfo: [String: Any]?) { guard let userInfo = userInfo, let data = userInfo["data"] as? [String: Any] else { return } let url = data["url"] as? String let title = data["title"] as? String let html = data["html"] as? String // 在这里处理数据,如保存到本地或同步到主App print("当前页面URL:", url ?? "未知") print("页面标题:", title ?? "未知") } }
二、SafariWebExtensionHandler无法识别SFSafariApplication的原因
SFSafariApplication是仅macOS平台可用的API,iOS系统中不存在这个类。
iOS的Safari App Extension开发中,页面交互与数据传递完全通过Web Extension标准API(如browser.runtime、browser.tabs)以及SFSafariPage、SFSafariExtensionViewController等iOS专属API实现,无需依赖SFSafariApplication。若代码中引用了该类,直接删除并替换为iOS对应的逻辑即可。
内容的提问来源于stack exchange,提问作者Damon Wagner
相关产品推荐
相关产品推荐

