iOS 分享扩展
用户在 Safari、照片或其他应用中点按“分享”,然后选择您的应用。WebViewGold 通过 JavaScript 变量 sharedData 把内容传给您的 Web 应用:文本和链接为纯文本,图片为 Base64 字符串。
Bolt + 分享扩展
书签工具、食谱收藏或灵感板,只有在一键就能保存时才真正好用。借助 WebViewGold,您的 Bolt 应用会出现在 iOS 和 Android 的分享面板中,用户分享的任何内容(一个链接、一段文本、一张照片)都会以 JavaScript 变量 sharedData 的形式到达您的 Web 应用。接下来由您的代码决定:预填表单、保存到后端,或者打开编辑器。
每个平台一次性 $109 起,或由我们的团队全程代劳,$698 起。
用户在 Safari、照片或其他应用中点按“分享”,然后选择您的应用。WebViewGold 通过 JavaScript 变量 sharedData 把内容传给您的 Web 应用:文本和链接为纯文本,图片为 Base64 字符串。
在 AndroidManifest.xml 中取消注释预先准备好的 intent filter(ACTION_SEND 用于 text/plain 和 image/*,ACTION_SEND_MULTIPLE 用于多张图片),应用图标就会出现在 Android 的分享对话框中。同一个变量,同样的处理方式:sharedData。
页面加载时检查 sharedData,区分链接、文本和图片,再把用户带到预填好的保存页面。在您自己的代码把内容发送到 Supabase、Firebase 或您自己的 API 之前,什么都不会被存储,所以主动权始终在用户手里。
把这段粘贴到 Bolt 中以实现 Web 应用端。检查结果,发布,然后在 WebViewGold 应用中测试。
为 WebViewGold 应用封装构建一个“从分享面板保存”的流程。创建 src/lib/shareInbox.ts,其中包含 readSharedContent():如果 navigator.userAgent 包含我的 WebViewGold 标识并且全局变量 sharedData 已设置,就返回 { kind: "link" | "image" | "text", value },以 http 开头的值视为链接,很长的 Base64 字符串视为图片;在开发环境中还要接受 ?debugShare= 查询参数,方便我在 Bolt 预览中测试。应用挂载后在 main.tsx 中调用它(立即调用一次,1 秒后再调用一次),收到内容时跳转到 /save。在 /save 上显示预览:链接调用 Netlify Function link-preview,在服务端获取页面标题和图片;图片则把 Base64 解码为 Blob,在 canvas 上缩小到最长边 1600px 后显示。保存时把图片上传到 Supabase Storage 存储桶 shares(路径 user_id/uuid.jpg),并向启用了行级安全的 saves 表插入一行。在 sessionStorage 中记住已处理的值,避免刷新后重复保存。如果用户未登录,把该项保留在 sessionStorage 中,登录后继续。
在过去5年我们尝试过的所有应用平台中,WebViewGold为我们带来了有史以来最短、最高效的上市时间。我不知道为什么没有更早发现你们,但我真的非常满意。目前我们的应用在iOS App Store和Google Play商店的下载量已超过6000次,没有任何问题!
当一次点按就能保存原本需要复制、切换应用再粘贴的内容时,分享目标才真正有价值。典型用途:
从 Safari 或 Chrome 分享一篇文章,应用在服务端获取标题和预览图,用户加个标签,点按“保存”即可。
一个食谱链接、地图应用里的一家餐厅、一个商品页面:存进收藏夹、旅行计划或心愿单,而不是散落在杂乱的笔记文件里。
把收据照片放进记账工具,把截图放进错误报告,把房间照片放进灵感板或物品清单。图片以 Base64 形式到达,可以直接上传。
把一则招聘信息或个人主页链接分享到求职跟踪工具或 CRM,直接进入预填好的“新建条目”表单,URL 已经解析完毕。
在任何应用中选中的文本都能变成一条笔记、一张抽认卡,或者您 AI 功能的提示词;如果分享的文本里包含链接,还会附上来源链接。
大约一小时,大部分时间花在您 Web 应用的保存页面上。
决定分享在您的 Bolt 应用中触发什么:保存链接、附加照片,还是开始一条笔记。一个明确的操作比一整个选项菜单更能促成转化。
按照 iOS 文档 在 WebViewGold Xcode 项目中开启分享扩展,然后把构建安装到真实的 iPhone 上。分享面板只会列出已安装应用的扩展,所以模拟器不适合用来测试。
在 AndroidManifest.xml 中只保留您真正处理的 filter:text/plain 用于链接和文本,image/* 用于单张照片,SEND_MULTIPLE 用于多张照片(Android 文档)。一个接受图片却对图片置之不理的分享目标,会给用户留下糟糕的第一印象。
页面加载时检查 typeof sharedData !== "undefined",并在短暂延迟后再检查一次。以 http 开头的值是链接;很长的 Base64 字符串是图片(JPEG 数据以 /9j/ 开头,PNG 以 iVBORw0KGgo 开头);其余都是文本,其中可能包含一个 URL。
如果用户尚未登录,就把分享的内容存入 sessionStorage,引导用户走完登录流程,之后再恢复保存页面。绝不要悄无声息地丢掉一次分享。
把图片解码为 Blob,缩小尺寸后上传;在服务器上获取链接标题,把记录存入 Supabase、Firebase 或您自己的 API;然后显示清晰的成功状态(这里很适合调用一次 successhaptic://)。
与框架无关;在您的应用挂载完成后调用一次 checkSharedContent()。把 YourAppToken 替换为您在 Config.swift(useragent_iphone、useragent_ipad)和 Config.java(USER_AGENT)中设置的自定义 User-Agent。
var inApp = navigator.userAgent.indexOf("YourAppToken") !== -1;
function classifyShared(raw) {
var value = String(raw).trim();
var b64 = value.replace(/^data:image\/[a-z+]+;base64,/i, "");
if (/^https?:\/\//i.test(value)) return { kind: "link", url: value };
if (b64.length > 1000 && /^[A-Za-z0-9+\/=\s]+$/.test(b64.slice(0, 4000))) {
return { kind: "image", base64: b64, mime: b64.indexOf("iVBORw0KGgo") === 0 ? "image/png" : "image/jpeg" };
}
var link = value.match(/https?:\/\/\S+/);
return { kind: "text", text: value, url: link ? link[0] : null };
}
function base64ToBlob(b64, mime) {
var bin = atob(b64.replace(/\s/g, ""));
var bytes = new Uint8Array(bin.length);
for (var i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
return new Blob([bytes], { type: mime });
}
function checkSharedContent() {
if (!inApp || typeof sharedData === "undefined" || !sharedData) return false;
var fingerprint = String(sharedData).length + ":" + String(sharedData).slice(0, 64);
if (sessionStorage.getItem("lastShare") === fingerprint) return false; // 已经处理过
sessionStorage.setItem("lastShare", fingerprint);
sessionStorage.setItem("pendingShare", JSON.stringify(classifyShared(sharedData)));
window.location.href = "/save"; // 您预填好的保存页面
return true;
}
window.addEventListener("load", function () {
if (!checkSharedContent()) setTimeout(checkSharedContent, 1000);
});在 iOS 上,分享目标是 Safari 标签页无法提供的原生集成之一,因此是应对准则 4.2 的有力论据。随之而来的还有几条规则。
在截图中展示分享流程,并在审核备注中用英文提到它(例如 "Share a link from Safari to save it")。审核人员只会认可他们找得到的功能。
扩展应当包含真正的功能,在营销文案中如实说明,并且不得包含营销内容、广告或应用内购买。让分享流程保持为一个干净的保存操作。
扩展应当与应用的内容和功能相关。接受食谱链接的食谱应用很合适;只会打开首页的分享目标则不合适。
分享的照片和链接可能包含个人数据。只上传用户确认过的内容,在隐私政策中加以说明,并在 App Privacy(照片、用户内容)和 Google Play 数据安全表单中申报。
可以。iOS 使用分享扩展,Android 使用 Share Intent;两种情况下,WebViewGold 都会通过同一个 JavaScript 变量 sharedData 把内容传给您的 Web 应用,所以一个处理程序就能覆盖两个平台。
文本和链接,以及以 Base64 字符串形式到达的图片。Android 还预先准备了一个可一次接收多张图片的 intent filter。其他文件类型(例如 PDF)不在文档所述的 API 范围内。
在 Android 上,已安装的 PWA 可以在基于 Chromium 的浏览器中通过 Web Share Target API 注册为分享目标。在 iOS 上,Safari 没有为 Web 应用提供同等功能,因此要出现在 iPhone 的分享面板中,就得依靠原生分享扩展。
把分享的内容保存在 sessionStorage 中,引导用户登录,再把他们带回内容仍在的保存页面。登录之后分享内容丢失,是这个流程中最常见的 bug。
没有任何单一功能能做到。它是一项醒目、实在的原生能力;再配合推送通知、离线处理和像原生应用一样的布局,就能有力地证明您的 Bolt 应用不只是一个网站。
结果相同,只是您需要投入的工作量不同。三种方式都附带审核通过保证和 7×24 小时人工支持。
$109 每个平台,一次性付费
WebViewGold 许可证:一个现成的 Xcode 或 Android Studio 项目。粘贴您的 URL,设置名称和图标,开启所需功能,构建并提交。永久免费更新。
在主页查看方案$349 每个许可证,一次性附加购买
无需 Mac、Xcode 或 Android Studio:在浏览器中完成配置,我们在云端构建两个应用,并将其交付到 App Store Connect 和 Play Console。
Cloud Builder 如何运作 试用免费演示$698 每个平台 $798
把您的 URL 和图标发给我们。我们的团队在 72 小时内完成配置、构建并交付您的应用,白标,附源码项目。两个平台共 $1,158。
Full Service 详情 服务提供方:冬季特惠价格有效期至 2026年12月31日。
App Store & Google Play 审核通过保证 – 否则 14 天内退款
想直接交给我们?Full Service:我们在 72 小时内完成配置、构建并交付,每个平台 $698 起。有疑问?通过 7×24 小时在线聊天联系我们。
退款依据我们 FAQ 中列出的条件:应用因非内容原因被 Apple 和/或 Google 拒审,并在购买后 14 天内提出申请。