关于 maui-deep-linking
这项 .NET MAUI 技能用于在 Android 和 iOS 上实现及调试深层链接,重点说明平台生命周期、链接验证、Shell 路由和常见配置故障。
主要功能
- 01处理 Android 冷启动和热启动
- 02配置已验证的 Android App Links
- 03涵盖 iOS Universal Link 入口
- 04检查域名关联文件和签名密钥
- 05在主线程执行 Shell 导航
- 06提供平台专属调试检查项
适用场景
- 01诊断 Android 链接弹出应用选择器
- 02在实体 iOS 设备调试 Universal Links
- 03排查应用不同生命周期状态下的链接故障
- 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.myappverified,而不只是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