点击时从 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)!)
但是也没用。
- 在 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
仅适用于 medium 和 large Widget。如果您使用 small Widget,您需要使用:
.widgetURL(URL(string: "widget://link0")!)
- 在您的 App 视图中使用
onOpenURL
: 接收 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.systemMedium
或 WidgetFamily.systemLarge
的小部件,将一个或多个 Link 控件添加到小部件的视图层次结构中。您可以同时使用 widgetURL
和 Link
控件。如果交互针对 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:)
、取决于您的应用使用的生命周期。
如果小部件不使用 widgetURL
或 Link
控件,系统会激活包含的应用程序并将 NSUserActivity
传递给 onContinueUserActivity(_:perform:)
、application(_:continue:restorationHandler:)
,或application(_:continue:restorationHandler:)
。用户 activity 的 userInfo 字典包含有关用户与之交互的小部件的详细信息。使用 WidgetCenter.UserInfoKey
中的键从 Swift 代码访问这些值。要从 Objective-C 访问 userInfo 值,请改用键 WGWidgetUserInfoKeyKind
和 WGWidgetUserInfoKeyFamily
。
我有一个带有两个文本的简单小部件(中等大小),我想要的是能够执行深度 link 以将用户引导至我的应用程序的特定部分,但我似乎找不到这样做的方法。
我写的视图(很简单):
HStack {
Text("FIRST ITEM")
Spacer()
Text("SECOND ITEM")
}
我已经尝试更换
Text("SECOND ITEM")
与
Link("SECOND ITEM destination: URL(string: myDeeplinkUrl)!)
但是也没用。
- 在 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
仅适用于 medium 和 large Widget。如果您使用 small Widget,您需要使用:
.widgetURL(URL(string: "widget://link0")!)
- 在您的 App 视图中使用
onOpenURL
: 接收 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.systemMedium
或WidgetFamily.systemLarge
的小部件,将一个或多个 Link 控件添加到小部件的视图层次结构中。您可以同时使用widgetURL
和Link
控件。如果交互针对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:)
、取决于您的应用使用的生命周期。
如果小部件不使用 widgetURL
或 Link
控件,系统会激活包含的应用程序并将 NSUserActivity
传递给 onContinueUserActivity(_:perform:)
、application(_:continue:restorationHandler:)
,或application(_:continue:restorationHandler:)
。用户 activity 的 userInfo 字典包含有关用户与之交互的小部件的详细信息。使用 WidgetCenter.UserInfoKey
中的键从 Swift 代码访问这些值。要从 Objective-C 访问 userInfo 值,请改用键 WGWidgetUserInfoKeyKind
和 WGWidgetUserInfoKeyFamily
。