深度链接

Universal Links 与 soar:// 自定义 scheme,从捕获到路由。

应用通过一个由三条捕获通道供给的单槽处理器,把外部 URL 路由到具体界面。本页讲两种入口类型、URL 如何变成 DeepLinkDestination,以及外壳在冷启动与热启动下如何消费它。它是 Integrated——自定义 scheme 开箱即用; Universal Links 需要一个 entitlement + 一个托管文件。

关键文件

两条入口通道

Prop

Type

模板已注册 soar scheme,且 entitlement 已存在但指向占位域名:

<!-- SoarStarterSwift.entitlements -->
<key>com.apple.developer.associated-domains</key>
<array>
  <string>applinks:example.com</string>
</array>

要启用 Universal Links,把 example.com 换成你的 LINKING_DOMAIN,然后在 https://<domain>/.well-known/apple-app-site-association 托管一个 apple-app-site-association 文件, 声明你应用的 appID<TeamID>.com.soarstarter.SoarStarterSwift)。在此之前,只有 soar:// scheme 可解析。

三个捕获来源 → 一个处理器

每个入口都汇入 DeepLinkHandler.set(_:)

.onOpenURL (RootView)                     ← 应用前台/启动时的 soar://
application(_:continue:) (AppDelegate)     ← Universal Link 点击(NSUserActivity)
notification tap (NotificationsController)  ← 推送载荷的 deeplink/url


DeepLinkHandler.pending : DeepLinkDestination?   (单槽,@Observable)


MainShellView 在 .onAppear + .onChange(of: pending) 时消费

RootView.onOpenURL 先让 Google 登录与 Supabase 的 auth 回调有机会认领该 URL(soar://auth-callback), 再把其余交给 DeepLinkHandler

解析一个 URL

DeepLinkResolver.resolve(_:) 归一化两种 URL 形态并映射到 DeepLinkDestination 枚举,未知路径返回 nil(会被忽略):

  • soar://todoshost 承载路由;对 https://domain/todospath 承载——解析器把二者拼接, 因此两种形态都能用。
  • ?route= 查询会覆盖路径,所以推送载荷可用查询参数携带目标(如 soar:///notifications?route=me)。
  • 路径会被归一化(补前导斜杠、折叠 //、去尾部斜杠)。

可路由的目标

路径目标落到
//home.homeHome 标签页
/component.component组件标签页
/showcase.showcaseShowcase 标签页(可移除的演示)
/todos.todosHome 标签页 → Todos
/me/profile.meMe 标签页
/personal-info.personalInfoMe → 个人信息
/notifications.notificationsMe → 通知
/permissions.permissionsMe → 权限
/refer.referMe → 推荐
/paywall.paywallMe → 付费墙(需要时提示登录)
/redeem-code.redeemCodeMe → 兑换码(提示登录)

冷启动 vs 热启动

MainShellView 在两处排空处理器,使两种情况都生效:

  • 热启动——.onChange(of: env.deepLinks.pending) 在外壳已在屏时,URL 一到即触发。
  • 冷启动——启动期间捕获的 URL 在外壳首次出现时仍在 pending 中,于是 .onAppear 消费它。

routePendingDeepLink() 调用 consume()(读取后清空槽),关闭抽屉,选中目标标签页,并设置该标签页的 导航路径。由于每个标签页有各自的 @State 路径,路由到 .todos 会设置 homePath = [.todos] 而不扰动 其他标签页的返回栈。付费墙 / 兑换目标在登出时会先弹出登录表单。

推荐分享流程

ReferralLinkProvider.inviteURL()LINKING_DOMAINhttps://<domain>/)构建分享 URL,未设域名时 回退到 soar:///。推荐界面用 ShareLink 包装它并触发 referral invite shared 分析事件——很适合放一个 回到应用的 ?route=refer 深度链接。

测试

自定义 scheme 链接在模拟器里就能用——无需服务端、无需真机:

xcrun simctl openurl booted "soar://todos"
xcrun simctl openurl booted "soar:///notifications?route=me"

内置的 DeepLinksShowcaseView(在可移除的 Showcase 中)把可路由目标列为可点按钮,便于快速手动巡检。 Universal Links 只能在 AASA 文件上线后于真机验证。

验证

  • xcrun simctl openurl booted "soar://todos" 打开 Home 标签页的 Todos。
  • 登出时 soar:///paywall 先弹登录表单,再进付费墙。
  • 未知路径(soar://nope)被忽略(不崩溃、不导航)。

相关页面

On this page