iOS Safari网页扩展:content.js如何访问UserDefaults变量?
iOS网页扩展实现主App共享表情符号到content.js的方案
核心思路
通过App Groups实现主App与扩展的共享UserDefaults,再借助扩展的原生桥接能力,把共享存储里的表情符号传递给content.js完成替换逻辑。
具体实现步骤
1. 配置App Groups实现数据共享
- 在苹果开发者后台,为主App和网页扩展创建并绑定同一个App Group(例如
group.com.yourdomain.fishextension) - 在Xcode中,分别给主App和Extension的
Signing & Capabilities面板添加App Groups能力,勾选刚才创建的组
2. 主App存储用户选择的表情符号
用户在主App选好表情后,写入共享UserDefaults:
// 主App代码 let sharedDefaults = UserDefaults(suiteName: "group.com.yourdomain.fishextension") sharedDefaults?.set("🐟", forKey: "selectedFishEmoji") sharedDefaults?.synchronize()
3. 扩展端将共享数据传递给content.js
方法一:注入全局变量(简单直接)
在Extension的ViewController中,读取共享存储的表情,注入为网页全局变量:
override func viewDidLoad() { super.viewDidLoad() let sharedDefaults = UserDefaults(suiteName: "group.com.yourdomain.fishextension") let selectedEmoji = sharedDefaults?.string(forKey: "selectedFishEmoji") ?? "🐠" // 注入全局变量到网页,确保content.js能读取到 let script = WKUserScript(source: "window.selectedFishEmoji = '\(selectedEmoji)';", injectionTime: .atDocumentStart, forMainFrameOnly: true) webView.configuration.userContentController.addUserScript(script) }
方法二:通过消息handler让JS主动获取
如果需要支持存储更新后主动拉取,可注册消息回调:
// Extension代码 override func viewDidLoad() { super.viewDidLoad() webView.configuration.userContentController.add(self, name: "getFishEmoji") } extension ViewController: WKScriptMessageHandler { func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { if message.name == "getFishEmoji" { let sharedDefaults = UserDefaults(suiteName: "group.com.yourdomain.fishextension") let emoji = sharedDefaults?.string(forKey: "selectedFishEmoji") ?? "🐠" // 把表情返回给JS webView.evaluateJavaScript("window.receiveFishEmoji('\(emoji)')") } } }
4. content.js执行替换逻辑
对应全局变量方案:
document.addEventListener('DOMContentLoaded', function() { const emoji = window.selectedFishEmoji || '🐠'; // 替换页面中所有fish为选中的表情 document.body.innerHTML = document.body.innerHTML.replace(/fish/gi, emoji); });
对应消息handler方案:
// 主动请求表情 window.webkit.messageHandlers.getFishEmoji.postMessage(null); // 接收返回的表情并执行替换 window.receiveFishEmoji = function(emoji) { document.body.innerHTML = document.body.innerHTML.replace(/fish/gi, emoji); };
关键注意点
- iOS网页扩展不支持主App直接向content.js发送实时消息,共享存储+原生桥接是最稳定的实现方式
- 必须确保App Groups配置完全一致,否则共享UserDefaults会读取不到数据
- 建议给表情设置默认值,避免存储为空时替换逻辑出错
内容的提问来源于stack exchange,提问作者Hazem
相关产品推荐
相关产品推荐

