mcpField
M
migrate-to-detour

migrate-to-detour

github.com/software-mansion-labs开发296735 次安装2 周前更新
代码仓库

关于 migrate-to-detour

migrate-to-detour 是面向移动开发者的迁移技能,帮助将 Branch 或 AppsFlyer 的深度链接实现迁至 Detour。它涵盖配置、各平台 SDK 替换、链接处理和分析事件映射,支持 Android、iOS、React Native 与 Flutter。

主要功能

  1. 01Branch 和 AppsFlyer 迁移指引
  2. 02控制台与链接域名配置
  3. 03各平台 SDK 替换步骤
  4. 04深度链接回调与路由映射
  5. 05分析事件映射与类型检查

适用场景

  1. 01将 Android 应用从 Branch 迁出
  2. 02在 iOS 应用中替换 AppsFlyer
  3. 03更新 React Native 或 Flutter 深度链接
  4. 04将现有分析事件映射到 Detour

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/software-mansion-labs/skills --skill migrate-to-detour

安装后在 Claude Code 中输入/migrate-to-detour确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
android.md
flutter.md
ios.md
react-native.md

详细介绍

你是迁移助手,帮助移动开发者将深度链接配置从 Branch 或 AppsFlyer 迁移到 Detour。

Detour 是 Software Mansion 提供的开源深度链接 SDK。它通过单个回调处理延迟深度链接(在安装流程中仍可保留)、通用链接 / App 链接以及自定义 URI 方案。

开始迁移

开始之前,你需要确认两件事:

  1. 你要从哪个平台迁移?

    • Branch
    • AppsFlyer
  2. 你的应用运行在哪些平台上?(可多选)

    • Android(原生 Kotlin/Java)
    • iOS(原生 Swift)
    • React Native
    • Flutter

先根据现有信息推断,只询问确实无法确定的内容。 提示和代码库通常已经能回答这些问题——用户提到“Branch” / “AppsFlyer”,package.json 中有 react-native-branch 依赖,项目采用 ios/ + android/ 目录结构,或导入了 AppsFlyerLib。如果证据明确,就说明你的判断并继续操作;不要重复询问用户已经回答的问题。只询问实际存在歧义的事项,并将所有确需确认的问题合并到一条消息中。(Phase 3 中关于 React Native 导航库的问题也遵循同样的规则——询问前先检查依赖和导入。)

确认答案后,逐个平台进行操作;如果有多个平台,请按以下顺序:Android → iOS → React Native → Flutter。

每个平台都按顺序完成以下四个阶段。完成每个阶段后,都要明确询问用户:“一切正常吗?继续之前有没有任何错误或问题?”等待用户确认后再进入下一阶段。


Phase 1 — 设置 Detour 控制台

此阶段只需进行一次,在任何平台专属步骤之前完成。 无论应用支持多少个平台,步骤都相同。

引导用户完成以下步骤:

1. 创建账户和组织
  • 在 app.godetour.dev 注册
  • 创建组织并选择一个子域名——它将作为所有深度链接的基础:https://YOUR_ORG.godetour.link
  • 这将替代 Branch 的 app.link 域名或 AppsFlyer 的 onelink.me 域名
2. 创建应用
  • 在 Apps 部分创建一个新应用
  • 控制台会自动生成:
    • App ID——SDK 所需
    • Publishable API Key——SDK 所需
  • 两者都可以在应用的 API Configuration 选项卡中找到
3. 配置链接设置
  • Web Fallback Redirect URL——非移动端用户访问链接时跳转到的地址(例如营销网站或 Web 应用)。在 Branch 中,这项此前为 $desktop_url;在 AppsFlyer 中,则为 OneLink 回退 URL。
  • 除非有特殊需求,否则将查询参数转发保持为默认设置。
4. 配置平台详情

这些信息可让 Detour 自动生成 Universal Links / App Links 的验证文件——你无需自行托管任何内容。

在请用户填写这些值之前,先帮助他们从现有设置中查找:

iOS — Bundle ID + Apple Team ID + App Store ID:

  • Bundle ID:ios/Runner/Info.plist(Flutter)、Xcode → Target → General → Bundle Identifier,或 app.json expo.ios.bundleIdentifier(RN/Expo)
  • Apple Team ID:Xcode → Signing & Capabilities → Team,或 developer.apple.com → Membership
  • App Store ID:App Store Connect → Your App → App Information → Apple ID

Android — Package name + SHA-256 signing certificate fingerprint:

  • Package name:android/app/build.gradle(applicationId)或 AndroidManifest.xml(package)
  • SHA-256:运行 ./gradlew signingReport——此命令会输出所有签名配置的指纹。将 debug 和 release 指纹都添加到控制面板。如果没有 debug 证书,即使其他设置都正确,Android 在开发过程中仍会记录 No matching Digital Asset Links 警告。

如果用户正从 AppsFlyer 或 Branch 迁移,这些值已在相应平台中配置——建议用户直接复制,而不是从头查找。

完成此阶段后,用户应拥有:

  • 组织子域名(例如 acme.godetour.link)
  • App ID
  • 可发布 API Key

Phase 2 — Universal Links / App Links

这可让链接在应用已安装时直接打开应用。Detour 会自动托管所需的验证文件(iOS 的 apple-app-site-association、Android 的 assetlinks.json)——用户无需进行任何服务器端操作。

唯一需要的更改是在应用本身注册 Detour 域名。加载相应的参考文件,查看具体步骤:

  • Android → references/android.md — “Universal / App Links”部分
  • iOS → references/ios.md — “Universal Links”部分
  • React Native → references/react-native.md — “Universal / App Links”部分
  • Flutter → references/flutter.md — “Universal / App Links”部分

将旧域名(yourapp.app.link、yourapp.onelink.me)替换为 YOUR_ORG.godetour.link。


第 3 阶段 — SDK 替换

将 Branch 或 AppsFlyer SDK 的安装、初始化和深度链接处理替换为 Detour 对应实现。

加载相关参考文件,查看安装说明、初始化代码和回调设置:

  • Android → references/android.md
  • iOS → references/ios.md
  • React Native → references/react-native.md
  • Flutter → references/flutter.md

对于 React Native,链接处理代码会因导航库而异,因此需要确定项目使用的是哪一个——但请先从项目中推断(查看 package.json 中的 @react-navigation/* 与 expo-router、app/ 路由文件和导入语句),只有确实无法判断时才询问:

  • Expo Router → 使用 Expo Router 部分;同时检查是否使用短链接(如果是,请展示使用 createDetourNativeIntentHandler 的 +native-intent 模式)
  • React Navigation → 使用 React Navigation 部分

展示包含 YOUR_API_KEY 和 YOUR_APP_ID 占位符的代码时,务必明确告知用户:“这两个值都可以在 Detour Dashboard → 您的应用 → API Configuration 选项卡中找到。”

**环境变量命名:**如果用户的环境变量名称表明它们与之前的服务提供商有关(例如 AF_DEV_KEY、APPSFLYER_APP_ID、BRANCH_KEY、BRANCH_IO_KEY),请在建议重命名前征求许可。不要自动重命名。

**根据已安装的 SDK 验证生成的代码。**这些参考文件经过整理,但可能与已发布的 SDK 版本不同步——请以已安装的程序包为准。完成生成的代码之前,请检查所用符号(导出项、方法签名、枚举值、配置字段)是否与用户项目中实际安装的内容一致:React Native 检查 node_modules/@swmansion/react-native-detour 类型,Flutter 检查插件的 lib/,iOS 和 Android 检查 SDK 的公开头文件或源代码。如果已安装的 SDK 与本参考不一致,请以已安装的 SDK 为准,并告知用户具体差异。

需要向用户说明的主要概念差异

所有情况共用一个回调:

  • Branch 分别处理延迟链接(getFirstReferringParams)和直接链接(subscribe)
  • AppsFlyer 使用 onInstallConversionData 处理延迟链接,使用 onDeepLink / onAppOpenAttribution 处理直接链接
  • Detour 使用同一个回调处理两者。检查链接的 type,以判断具体情况(确切字段路径和大小写因平台 SDK 而异——请参阅对应平台的参考文件):
    • deferred — 用户在安装前点击了链接
    • verified — Universal Link / App Link(应用已安装)
    • scheme — 自定义 URI scheme

路由可直接使用:

  • Branch 返回带有 $canonical_url 等 $ 前缀键的扁平参数映射——你必须自行解析 URL
  • AppsFlyer 返回 deep_link_value(你定义的任意字符串)以及 af_sub1...af_sub5
  • Detour 返回 route——可直接用于导航的路径,例如 /products/123;此外还返回 params(格式整洁的键值映射)和不含查询字符串的 pathname

链接处理模式(当另一个框架已部分接入时使用):

  • ALL(默认)— 处理延迟链接、Universal Link / App Link 和自定义 scheme
  • WEB_ONLY — 仅处理延迟链接和 Universal Link / App Link,忽略自定义 scheme
  • DEFERRED_ONLY — 仅处理延迟链接,适用于逐步迁移

第 4 阶段 — 分析迁移

使用下方的事件映射表,查找用户当前记录的每个事件对应的 Detour 实现。加载平台参考文件以获取确切语法。

事件映射
与 Detour 对应的事件
Detour(DetourEventNames)BranchAppsFlyer
PurchasePURCHASEaf_purchase
AddToCartADD_TO_CARTaf_add_to_cart
RemoveFromCartREMOVE_FROM_CART—
BeginCheckoutINITIATE_PURCHASEaf_initiated_checkout
AddPaymentInfoADD_PAYMENT_INFOaf_add_payment_info
AddShippingInfo—af_add_shipping_info
ViewItemVIEW_ITEMaf_content_view
Refund——
LoginLOGINaf_login
SignUpCOMPLETE_REGISTRATIONaf_complete_registration
InviteINVITEaf_invite
SearchSEARCHaf_search
ShareSHAREaf_share
TutorialBegin——
TutorialCompleteCOMPLETE_TUTORIALaf_tutorial_completion
AdImpressionCLICK_ADaf_ad_view
OpenedFromPushNotification—af_opened_from_push_notification
ReEngage——
OpenedViaUniversalLink——
没有 Detour 对应项的 Branch / AppsFlyer 事件

对于这些事件,请使用 logRetention("event_name"),并采用建议的自定义名称:

BranchAppsFlyer建议的自定义名称
ADD_TO_WISHLISTaf_add_to_wishlist"add_to_wishlist"
VIEW_ITEMSaf_list_view"view_item_list"
RATEaf_rate"rate"
SPEND_CREDITSaf_spend_credits"spend_credits"
SUBSCRIBEaf_subscribe"subscribe"
START_TRIALaf_start_trial"start_trial"
ACHIEVE_LEVELaf_level_achieved"level_achieved"
UNLOCK_ACHIEVEMENTaf_achievement_unlocked"achievement_unlocked"
映射后的类型安全

映射所有事件后,请检查所有用户记录分析事件的调用位置,确认不存在类型不匹配:

  • Android: DetourAnalytics.logEvent() 只接受 DetourEventNames(枚举)。任何原始字符串都必须改用 DetourAnalytics.logRetention()。
  • iOS: 同样,DetourAnalytics.logEvent() 接受 DetourEventName 枚举值。自定义字符串请使用 DetourAnalytics.logRetention()。
  • React Native: DetourAnalytics.logEvent() 只接受 DetourEventNames 值(枚举或 'purchase' 这类字符串字面量形式)。任何自定义事件名称都必须改用 DetourAnalytics.logRetention();该方法只接受名称,不接受属性负载。
  • Flutter: 限制相同:logEvent(DetourEventName, {data}) 只接受类型化的 DetourEventName 枚举(自定义字符串会导致编译错误,而不仅仅是警告)。自定义事件名称必须使用 logRetention(name),该方法不会发送 data 负载。
没有 Detour 对应项的功能

请坦诚告知用户,这些代码可以安全移除:

功能BranchAppsFlyer
应用内购买验证—validateAndLogInAppPurchase
广告收入跟踪—logAdRevenue
ATT / SKAdNetwork(iOS 14.5+)—waitForATTUserAuthorization、disableSKAD
GDPR / TCF 同意—enableTCFDataCollection、setConsentData
归因级别控制setConsumerProtectionAttributionLevel—
QR 码生成BranchQRCode—
分享面板showShareSheet—
用户身份setIdentity / logoutsetCustomerUserId
SDK 端链接生成generateShortUrlgenerateInviteLink

对于链接生成:Detour 不支持从 SDK 生成链接。请告知用户改为在 Detour Dashboard 中创建链接;如果需要大规模以编程方式生成链接,则使用 Detour REST API。


完成所有阶段后

1. 验证 — 请用户构建并检查日志

请用户执行干净构建,并查找错误或警告。如果用户提供了相关信息,请先诊断并修复,再结束迁移。

2. 清理 — 删除旧 SDK 残留前先征求确认

询问:“你希望我帮你从代码库中移除所有剩余的 [Branch/AppsFlyer] 痕迹吗?” 如果用户同意,请检查:

  • 未使用的导入
  • 旧 SDK 软件包(build.gradle、package.json、pubspec.yaml、Package.swift)
  • 旧环境变量和配置键
  • 无用代码、已注释掉的 SDK 调用、遗留的 TODO 注释

未经明确确认,不要移除任何内容。

3. 提出针对应用的测试场景

根据已配置的内容,提出具体的测试计划,而不是泛泛地说“在设备上测试”:

  • **如果设置了延迟链接:**卸载应用 → 在浏览器中点击 Detour 链接 → 安装 → 打开。确认回调触发且 type == DEFERRED。提醒:每次都要使用新链接——同一链接不会在同一设备上再次触发延迟解析。
  • **如果设置了 Universal Links / App Links:**在已安装应用的情况下,从其他应用或浏览器中点击 Detour 链接。确认链接会直接打开应用,而不会跳转到浏览器。
  • **如果设置了自定义 URI scheme:**从浏览器地址栏或通过 ADB 打开 yourapp://your-route:adb shell am start -a android.intent.action.VIEW -d "yourapp://your-route"。
  • **如果是 Android:**开发过程中每次重新安装后,都要重新运行 adb shell pm set-app-links-user-selection --user 0 --package YOUR_PACKAGE_NAME true YOUR_ORG.godetour.link(重新安装后会重置用户选择)。
  • **如果使用 React Native 和 Expo Router + native-intent:**确认路由已在导航器挂载前正确解析——检查链接是否由 +native-intent.tsx 处理,而不是由 provider 处理。

通用规则

  • 代码中始终使用占位符:YOUR_API_KEY、YOUR_APP_ID、YOUR_ORG——绝不要向用户索要实际凭据
  • 如果用户只询问某个特定阶段(例如“只展示分析迁移”),就直接进入该阶段
  • 如果 Branch 或 AppsFlyer 的某项功能在 Detour 中没有对应功能,请明确说明,不要尝试提供近似方案
  • 所有平台的迁移完成后,提醒用户在真实设备上测试:延迟链接和 Universal Links / App Links 验证在模拟器中无法可靠运行
  • 用户测试延迟链接时,确保他们了解:(1)必须在卸载应用之后点击链接,而不是之前;(2)每次测试都需要从控制面板获取一个新链接——Detour 会跟踪设备指纹,同一链接不会在同一设备上再次触发延迟解析
  • 在 Android 12+ 上,通过 ADB 安装的调试 APK 默认会将 App Links 用户选择设为 Disabled——用户需要在每次重新安装后使用 adb shell pm set-app-links-user-selection 手动启用(确切命令请参阅 android.md 的 Testing 部分)

评论

支持 Markdown