点击时从 SwiftUI 小部件执行深度链接

Perform a deeplink from SwiftUI widget on tap

我有一个带有两个文本的简单小部件(中等大小),我想要的是能够执行深度 link 以将用户引导至我的应用程序的特定部分,但我似乎找不到这样做的方法。

我写的视图(很简单):

HStack {
    Text("FIRST ITEM")    
    Spacer()
    Text("SECOND ITEM")
}

我已经尝试更换

Text("SECOND ITEM")

Link("SECOND ITEM destination: URL(string: myDeeplinkUrl)!)

但是也没用。

  1. Widget 视图中,您需要创建一个 Link 并设置其 destination url:
struct SimpleWidgetEntryView: View {
    var entry: SimpleProvider.Entry

    var body: some View {
        Link(destination: URL(string: "widget://link1")!) {
            Text("Link 1")
        }
    }
}

请注意,Link 仅适用于 mediumlarge Widget。如果您使用 small Widget,您需要使用:

.widgetURL(URL(string: "widget://link0")!)
  1. 在您的 App 视图中使用 onOpenURL:
  2. 接收 url
@main
struct WidgetTestApp: App {
    var body: some Scene {
        WindowGroup {
            Text("Test")
                .onOpenURL { url in
                    print("Received deep link: \(url)")
                }
        }
    }
}

也可以通过覆盖在 SceneDelegate 中接收深层链接:

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>)

您可以在这个线程中找到有关如何使用此功能的更多说明:


这是一个 GitHub repository 包含不同的 Widget 示例,包括 DeepLink Widget。

此外,您可以使用 AppDelegate(如果您不使用 SceneDelegate):

.widgetURL(URL(string: "urlsceheme://foobarmessage"))

// OR

Link(destination: URL(string: "urlsceheme://foobarmessage")!) {
    Text("Foo")
}

AppDelegate

内设置此代码
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
   let message = url.host?.removingPercentEncoding // foobarmessage
   return true
}

请参阅 docs响应用户交互

当用户与您的小部件交互时,系统会启动您的应用程序来处理请求。当系统激活您的应用程序时,导航至与小部件内容相对应的详细信息。您的小部件可以指定一个 URL 来通知应用程序要显示的内容。要在您的小部件中配置自定义 URL:

  • 对于所有小部件,将 widgetURL(_:) 视图修饰符添加到小部件视图层次结构中的视图。如果小部件的视图层次结构包含多个 widgetURL 修饰符,行为未定义
  • 对于使用 WidgetFamily.systemMediumWidgetFamily.systemLarge 的小部件,将一个或多个 Link 控件添加到小部件的视图层次结构中。您可以同时使用 widgetURLLink 控件。如果交互针对 Link 控件,系统将使用该控件中的 URL。对于小部件中其他任何地方的交互,系统使用 widgetURL 视图修饰符中指定的 URL

例如,显示游戏中单个角色详细信息的小部件可以使用 widgetURL 打开应用程序以查看该角色的详细信息。

@ViewBuilder
var body: some View {
    ZStack {
        AvatarView(entry.character)
            .widgetURL(entry.character.url)
            .foregroundColor(.white)
    }
    .background(Color.gameBackground)
}

如果小部件显示字符列表,则列表中的每个项目都可以在 Link 控件中。每个 Link 控件为其显示的特定字符指定 URL

当小部件收到交互时,系统会激活包含的应用程序并将 URL 传递给 onOpenURL(perform:)application(_:open:options:)application(_:open:)取决于您的应用使用的生命周期

如果小部件不使用 widgetURLLink 控件,系统会激活包含的应用程序并将 NSUserActivity 传递给 onContinueUserActivity(_:perform:)application(_:continue:restorationHandler:),或application(_:continue:restorationHandler:)。用户 activity 的 userInfo 字典包含有关用户与之交互的小部件的详细信息。使用 WidgetCenter.UserInfoKey 中的键从 Swift 代码访问这些值。要从 Objective-C 访问 userInfo 值,请改用键 WGWidgetUserInfoKeyKindWGWidgetUserInfoKeyFamily