mcpField
M
maui-deep-linking

maui-deep-linking

github.com/davidortinau开发17643 次安装16 周前更新
代码仓库

关于 maui-deep-linking

这项 .NET MAUI 技能用于在 Android 和 iOS 上实现及调试深层链接,重点说明平台生命周期、链接验证、Shell 路由和常见配置故障。

主要功能

  1. 01处理 Android 冷启动和热启动
  2. 02配置已验证的 Android App Links
  3. 03涵盖 iOS Universal Link 入口
  4. 04检查域名关联文件和签名密钥
  5. 05在主线程执行 Shell 导航
  6. 06提供平台专属调试检查项

适用场景

  1. 01诊断 Android 链接弹出应用选择器
  2. 02在实体 iOS 设备调试 Universal Links
  3. 03排查应用不同生命周期状态下的链接故障
  4. 04验证 Shell 路由和域名关联配置

安装

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

$npx skills add https://github.com/davidortinau/maui-skills --skill maui-deep-linking

安装后在 Claude Code 中输入/maui-deep-linking确认已加载。

附带文件references/deep-linking-api.md

详细介绍

.NET MAUI 深度链接

平台注意事项

Android
  • App Links(不只是深度链接)必须在 IntentFilter 上设置 AutoVerify = true。 否则,Android 会显示选择对话框,而不是直接打开你的应用。
  • 在 OnCreate 和 OnNewIntent 中都处理 Intent。 冷启动时会触发 OnCreate;应用已在运行时会触发 OnNewIntent。漏掉任意一个都会导致链接在一种场景下悄然失效。
// ❌ Only handles cold-start links
protected override void OnCreate(Bundle? savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    HandleDeepLink(Intent);
}

// ✅ Handles both cold-start and warm-start links
protected override void OnCreate(Bundle? savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    HandleDeepLink(Intent);
}
protected override void OnNewIntent(Intent? intent)
{
    base.OnNewIntent(intent);
    HandleDeepLink(intent);
}
  • SHA-256 指纹必须与测试构建所用的签名密钥匹配。 Debug 和 Release 构建使用不同的密钥——请相应更新 assetlinks.json,否则验证会悄然失败。
  • 使用以下命令检查验证状态:
    adb shell pm get-app-links com.example.myapp
    
    查看状态是否为 verified,而不只是 ask。
iOS
  • ⚠️ Universal Links 在模拟器中无法使用。 你必须在实体设备上测试。
  • AASA 更改最多需要 24 小时才能通过 Apple 的 CDN 传播(iOS 14+)。开发期间,可以使用 ?mode=developer 查询参数,或使用 Apple 的 CDN 诊断工具:swcutil dl -d example.com。
  • 处理全部三个入口点:FinishedLaunching、ContinueUserActivity 和 SceneWillConnect。漏掉任何一个都会导致链接在特定应用状态下失效(冷启动、后台恢复或基于场景的启动)。
  • 关联域名授权中必须包含 applinks: 前缀。 只写 example.com 而不写 applinks:example.com 会导致静默失败。

常见错误

忘记调用 MainThread.BeginInvokeOnMainThread

深度链接回调可能在后台线程触发。Shell 导航必须在主线程上运行。

// ❌ May crash — GoToAsync called off the main thread
static void HandleUniversalLink(string? url)
{
    if (string.IsNullOrEmpty(url)) return;
    Shell.Current.GoToAsync(MapToRoute(url));
}

// ✅ Dispatch to main thread
static void HandleUniversalLink(string? url)
{
    if (string.IsNullOrEmpty(url)) return;
    MainThread.BeginInvokeOnMainThread(async () =>
        await Shell.Current.GoToAsync(MapToRoute(url)));
}
导航前未注册路由

在 AppShell 构造函数中注册 Shell 路由,且必须在任何深度链接触发之前完成。如果路由不存在,GoToAsync 会静默抛出异常或导航到根页面。

自定义 URI 方案与 App Links / Universal Links
方式已验证回退到浏览器推荐
自定义 URI 方案(myapp://)否否仅用于应用间通信
Android App Links(https://)是是✅ 生产环境网页链接
iOS Universal Links(https://)是是✅ 生产环境网页链接

⚠️ 自定义 URI 方案未经验证——任何应用都可以注册相同的方案。面向用户的 URL 请使用 https:// App Links / Universal Links。


调试检查清单

  • Android:MainActivity 上的 IntentFilter 设置了 AutoVerify = true
  • Android:/.well-known/ 下的 assetlinks.json 包含当前签名密钥对应的正确 SHA-256
  • Android:在 OnCreate 和 OnNewIntent 中都处理了 Intent
  • Android:使用 adb shell pm get-app-links 验证
  • iOS:关联域名授权中包含 applinks:example.com(而不只是 example.com)
  • iOS:/.well-known/apple-app-site-association 下的 AASA 文件包含正确的 Team ID
  • iOS:处理了全部三个生命周期入口点
  • iOS:已在实体设备(而非模拟器)上测试
  • Shell 路由已在深度链接回调触发前注册
  • 导航已分发到主线程

评论

支持 Markdown