移动/游戏
在 Capacitor 应用中实现深度链接与通用链接(自定义…
当需要让用户通过链接打开 Capacitor 应用并跳转到指定页面时,用这套做法配置深度链接、通用链接和 App Links。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在 Capacitor 应用中实现深度链通用
解决思路
- 安装插件:运行 `npm install @capacitor/app` 和 `npx cap sync`。
- 监听深度链接打开事件:使用 `App.addListener('appUrlOpen', (event) => {...})`,从 `event.url` 解析 URL 并导航。
- 编写 `handleDeepLink(url)` 函数:根据 `url.pathname`(或 `url.host + url.pathname`)路由,例如 `/product/` 取 productId 跳转 `/product/${productId}`,`/user/` 跳转 `/profile/${userId}`,`/login` 跳转 `/login`,否则跳转 `/`。
- 配置 iOS 自定义 URL Scheme:在 `ios/App/App/Info.plist` 中添加 `CFBundleURLTypes`,包含 `CFBundleURLName`(如 `com.yourcompany.yourapp`)和 `CFBundleURLSchemes`(如 `myapp`、`myapp-dev`)。
- 配置 Android 自定义 URL Scheme:在 `android/app/src/main/AndroidManifest.xml` 的 MainActivity 中添加 intent-filter,包含 `android.intent.action.VIEW`、`DEFAULT`、`BROWSABLE` 分类以及 `<data android:scheme="myapp" />`。
- 测试自定义 Scheme:iOS 模拟器用 `xcrun simctl openurl booted "myapp://product/123"`;Android 用 `adb shell am start -a android.intent.action.VIEW -d "myapp://product/123"`。
- 启用 iOS Associated Domains:在 Xcode 中选择 App target → Signing & Capabilities → + Capability → Associated Domains,添加 `applinks:myapp.com`。
- 创建并托管 apple-app-site-association 文件:放在 `https://myapp.com/.well-known/apple-app-site-association`,JSON 中包含 `applinks.details` 的 `appID`(如 `TEAMID.com.yourcompany.yourapp`)和 `paths`(如 `/product/*`、`/user/*`、`/invite/*`、`NOT /api/*`);要求 HTTPS、Content-Type 为 `application/json`、无重定向、位于根域名。
- 在 iOS Info.plist 中添加 `com.apple.developer.associated-domains` 数组,包含 `applinks:myapp.com` 和 `applinks:www.myapp.com`。
- 验证 Universal Links:用 `curl -I https://myapp.com/.well-known/apple-app-site-association` 检查 AASA 文件,用 `curl "https://app-site-association.cdn-apple.com/a/v1/myapp.com"` 检查 Apple CDN 缓存。
- 创建并托管 assetlinks.json:放在 `https://myapp.com/.well-known/assetlinks.json`,包含 `relation: ["delegate_permission/common.handle_all_urls"]`、`namespace: "android_app"`、`package_name` 和 `sha256_cert_fingerprints`。
- 获取 SHA256 指纹:调试密钥用 `keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android`;发布密钥用 `keytool -list -v -keystore release.keystore -alias your-alias`;从 APK 用 `keytool -printcert -jarfile app-release.apk`。
- 配置 Android App Links:在 AndroidManifest.xml 的 MainActivity 中添加 `android:autoVerify="true"` 的 intent-filter,包含 `VIEW`、`DEFAULT`、`BROWSABLE` 分类以及 `<data android:scheme="https" />`、`<data android:host="myapp.com" />` 和各 `pathPrefix`(如 `/product`、`/user`、`/invite`)。
- 验证 App Links:用 `curl https://myapp.com/.well-known/assetlinks.json` 检查文件,使用 Google 的 Digital Asset Links 验证器,用 `adb shell pm get-app-links com.yourcompany.yourapp` 检查设备上的链接处理。
- React Router 集成:在 `useEffect` 中监听 `appUrlOpen` 并用 `history.push(path)` 导航;同时用 `App.getLaunchUrl()` 处理冷启动,若 `result?.url` 存在则解析并 `history.push(path)`;`getPathFromUrl` 中若 `url.protocol === 'myapp:'` 返回 `'/' + url.host + url.pathname`,否则返回 `url.pathname + url.search`。
- Vue Router 集成:在 `onMounted` 中监听 `appUrlOpen` 并用 `router.push(path)` 导航;同时用 `App.getLaunchUrl()` 处理冷启动并 `router.push(path)`。
- 处理延迟深度链接:用 `Preferences.get({ key: 'firstLaunch' })` 判断是否首次启动,首次启动时设置 `firstLaunch` 为 `false`,调用 `fetchDeferredLink()` 获取延迟链接并 `handleDeepLink(new URL(deferredLink))`。
- 处理查询参数:从 `url.searchParams.get('source'/'campaign'/'ref')` 读取参数,记录归因事件(如 `analytics.logEvent('deep_link_open', {...})`),并在导航时传递 state。
- 处理 OAuth 回调:在 `appUrlOpen` 中判断 `url.pathname === '/oauth/callback'`,读取 `code`、`state`、`error`;若有 error 则 `handleOAuthError(error)`;若 code 存在且 `validateState(state)` 通过则 `exchangeCodeForToken(code)` 并跳转 `/home`。
- 按测试矩阵验证:自定义 scheme 用 `myapp://path`;Universal Link 冷启动(应用关闭时点击链接)、热启动(应用后台时点击链接)、Safari 中输入 URL;App Link 冷启动、Chrome 中点击链接。
- 使用调试工具:iOS 用 `codesign -d --entitlements - App.app | grep associated-domains` 检查 entitlement,用 `xcrun simctl erase all` 重置 Universal Links 缓存;Android 用 `adb shell dumpsys package d | grep -A5 "Package: com.yourcompany.yourapp"` 检查已验证链接。
- 排查常见问题:Universal Links 不工作检查 AASA 文件、SSL、entitlements;App Links 未验证检查 assetlinks.json、指纹;链接在浏览器打开检查 intent-filter、autoVerify;冷启动未处理使用 `App.getLaunchUrl()`;模拟器问题重置模拟器并重新构建。
适用边界 · 注意事项
- 不需要从外部链接打开应用或跳转页面的场景
- 无法控制或托管 HTTPS 域名下 `.well-known` 文件的场景(此时 Universal Links 和 App Links 无法使用,只能用自定义 URL Scheme)