二维码扫描器
qrcode:// 会打开原生扫描器,并在应用内加载扫描到的 URL,所以二维码里请编码您自有域名的 URL。商品条形码请使用 barcodescanner://,并读取 barcodescanresult。
Claude Code
WebViewGold 以 URL scheme 和少量全局 JavaScript 变量的形式,把原生能力开放给您的 Web 应用。这让它们非常适合交给代理来做:把文档指给 Claude Code,告诉它您启用了哪些功能,它就会把这些功能接入您现有的组件。下面介绍具体做法,同时避免代理编造 API 名称。
每个平台一次性 $109 起,或由我们的团队全程代劳,$698 起。
您的 Web 应用通过导航到某个 scheme 来请求封装层执行操作,例如 window.location.href = "bioauth://"。封装层拦截这次导航,执行原生操作,然后通过以下方式之一返回结果:调用您定义的全局函数(onBioAuthSuccess())、注入全局变量(onesignalplayerid、nativePushEnabled、barcodescanresult),或者加载一个 URL(二维码扫描器会在应用内打开扫描到的 URL)。无需安装 SDK,也无需打包任何东西。
所有内容都记录在一个机器可读的文件中:webviewgold.com/llms-full.txt。让 Claude Code 在写代码之前先阅读相关章节,它就会使用准确的 scheme 名称,而不是听起来似是而非的名称。本文中的每个 scheme 都已对照该文件核实过。
根据您在 Config.swift 和 Config.java 中开启的功能调整功能列表。
我们的 Web 应用同时运行在用 WebViewGold 构建的原生 iOS 和 Android 应用中。原生功能通过导航到 URL scheme 来触发,结果以全局 JavaScript 变量或全局回调函数的形式返回。在编写任何代码之前,先获取 https://www.webviewgold.com/llms-full.txt,并阅读以下章节:Push Notifications API、Biometric Authentication API、QR Code Scanner API、App Sharing Dialog API、Haptic Feedback API、File Downloader API、HTML5 Geolocation API。只使用该文件中出现过的 scheme 名称。 然后在 src/lib/native.ts 中实现:isNativeApp()(User-Agent 包含标记 WebViewGoldApp)、callNative(scheme)(仅在 isNativeApp() 为 true 时设置 window.location.href,否则返回 false),以及一个 readInjected(name, timeoutMs) 辅助函数,用于轮询封装层注入的全局变量。 把以下功能接入现有界面,每一项都放在 isNativeApp() 判断之后,并提供 Web 端的备用方案: 1. 推送:一个调用 registerpush:// 的“开启通知”按钮;一个调用 checkNativePushPermissions:// 并读取 nativePushEnabled 的设置项;登录后调用 getonesignalplayerid://,读取 onesignalplayerid 并通过我们的 API 保存到用户资料中。 2. 生物识别:为 /wallet 路由加上 Face ID / 指纹锁,使用 bioauth:// 和三个回调 onBioAuthSuccess、onBioAuthFailure(errorCode, errorMessage)、onBioAuthUnavailable;不可用时,退回到我们现有的重新输入密码流程。 3. 二维码签到:一个调用 qrcode:// 的“扫描”按钮;我们的二维码包含指向自有域名的 URL,因此要处理它们打开的 /checkin 路由。 4. 分享:在原生环境中,把“复制链接”按钮替换为 shareapp://message?=TEXT&url=URL,两个值都要用 encodeURIComponent 编码。 5. 触觉反馈:订单完成后调用 successhaptic://,表单校验出错时调用 errorhaptic://,切换标签时调用 lighthaptic://。在 iOS 上,使用文档中的 iframe 技巧,避免触觉反馈打断页面导航。 6. 下载:图片下载使用 savethisimage://?url=IMAGE_URL;PDF 链接保持为普通链接。 7. 定位:继续使用 navigator.geolocation,但在第一次请求之前先显示一个说明权限用途的页面。 最后报告每项功能需要我启用哪些 Config.swift / Config.java 选项,以及哪些 Info.plist 或 AndroidManifest 条目。
小巧、不依赖任何框架,也是代码中唯一知道 User-Agent 的地方。
// src/lib/native.ts
export function isNativeApp() {
return typeof navigator !== "undefined" && navigator.userAgent.indexOf("WebViewGoldApp") !== -1;
}
export function callNative(scheme) {
if (!isNativeApp()) return false;
window.location.href = scheme;
return true;
}
// Wait for a variable the wrapper injects, e.g. onesignalplayerid or nativePushEnabled
export function readInjected(name, timeoutMs) {
return new Promise(function (resolve, reject) {
var started = Date.now();
(function check() {
if (typeof window[name] !== "undefined") return resolve(window[name]);
if (Date.now() - started > (timeoutMs || 3000)) return reject(new Error(name + " not injected"));
setTimeout(check, 100);
})();
});
}
我很高兴购买了这个应用!非常简单,文档也很棒。联系客服后,他们回复很快且非常友好,一天之内就解决了我的问题。10/10,值得推荐。
需要在封装层中开启推送服务(iOS 上通过 Config.swift 中的 kPushEnabled 和 oneSignalID 开启 OneSignal,Android 上需要 PUSH_ENABLED 以及 build.gradle 中的 ID)。把 askforpushpermissionatfirstrun(iOS)和 requirePush(Android)设为 false,这样何时弹出权限请求就由您决定。
import { callNative, readInjected } from "./native";
// 1. Ask at the right moment (after onboarding, not on first launch)
export function askForPush() {
return callNative("registerpush://");
}
// 2. Is push currently allowed? Sets window.nativePushEnabled
export async function isPushEnabled() {
if (!callNative("checkNativePushPermissions://")) return null;
return readInjected("nativePushEnabled", 2000);
}
// 3. Store the OneSignal subscription ID on the user so the server can target this device
export async function syncPushId(saveToProfile) {
if (!callNative("getonesignalplayerid://")) return;
var id = await readInjected("onesignalplayerid", 3000);
await saveToProfile(id);
}
// 4. A local reminder in two hours, no push service needed
export function scheduleLocalReminder(title, message, url) {
var seconds = 2 * 60 * 60;
callNative("sendlocalpushmsg://push.send?s=" + seconds + "=msg!" + message + "&!#" + title + "&!#" + url);
}在 iOS 上,项目需要在 Info.plist 中添加 Face ID 用途说明(NSFaceIDUsageDescription);Android 使用系统的 BiometricPrompt,无需额外配置。封装层会调用这些全局函数,所以要把它们定义在 window 上。
import { callNative } from "./native";
export function requireBiometrics(onPass, onFallback) {
window.onBioAuthSuccess = function () { onPass(); };
window.onBioAuthFailure = function (errorCode, errorMessage) {
console.warn("bioauth failed", errorCode, errorMessage);
onFallback();
};
window.onBioAuthUnavailable = function () { onFallback(); };
if (!callNative("bioauth://")) onFallback(); // browser: use the password re-entry instead
}
// Security note from the documentation: treat the success callback as a UI gate only.
// Keep sensitive actions behind a server-side session check as well.qrcode:// 会打开原生扫描器,并在应用内加载扫描到的 URL,所以二维码里请编码您自有域名的 URL。商品条形码请使用 barcodescanner://,并读取 barcodescanresult。
shareapp://message?=TEXT&url=URL 在两个平台上都会打开系统分享对话框。两个值都要编码。在 Android 上,ShareIntent API 还能让其他应用把内容分享到您的应用中。
lighthaptic://、heavyhaptic://、successhaptic://、warninghaptic://、errorhaptic://;mediumhaptic:// 仅限 iOS。文档中提供了一个 iframe 辅助方法,确保调用不会取消正在进行的页面导航。
savethisimage://?url=… 会把图片保存到相册。以 .pdf、.docx、.xlsx、.mp3 及其他列出的扩展名结尾的链接会以原生方式下载;可以通过 extentionARY(Config.swift)或 downloadableExtension(Config.java)扩展这个列表,也可以针对 Content-Disposition 响应头启用 autodownloader / AUTO_DOWNLOAD_FILES。
直接使用 navigator.geolocation 即可;封装层会显示原生的权限对话框。iOS 需要 HTTPS 以及 Info.plist 中的位置用途说明文字,Android 需要在 Config.java 中把 requireLocation 设为 true,并确保清单条目齐全。
| 功能 | iOS(Config.swift / 项目) | Android(Config.java / 项目) |
|---|---|---|
| 推送(OneSignal) | kPushEnabled、oneSignalID;文档 | PUSH_ENABLED、build.gradle 中的 ID;文档 |
| 生物识别 | Info.plist 中的 Face ID 用途说明;文档 | 无需设置;文档 |
| 二维码 / 条形码 | 相机用途说明;qrcodelinks 决定扫描到的 URL 在哪里打开;文档 | requireCamera、QR_CODE_URL_OPTIONS;文档 |
| 分享、触觉反馈 | 无需启用;文档 | 无需启用;文档 |
| 下载 | extentionARY、autodownloader;文档 | downloadableExtension、AUTO_DOWNLOAD_FILES、requireStorage;文档 |
| 定位 | Info.plist 中的位置用途说明;文档 | requireLocation;文档 |
它只需要获取该文件一次。如果您的环境禁止访问网络,就把文件下载到仓库中(例如 docs/webviewgold-llms-full.txt),并在 CLAUDE.md 中引用这个路径。
因为这样服务器就能给某一个特定的人发送推送(订单已发货、有新回复)。没有这个 ID,您只能向用户分组群发。
能,包括 Config.swift 和 Config.java 中的值以及权限说明文字。但签名和描述文件不要交给它;项目配置指南说明了其中的边界。
不会有任何可见的效果。例如,在没有启用推送服务的情况下调用 registerpush://,什么也不会发生。请先在封装层中启用该功能,再测试调用。
结果相同,只是您需要投入的工作量不同。三种方式都附带审核通过保证和 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 天内提出申请。