iOS 来自锁定屏幕和通知中心的 Today Widget 通用链接
iOS Today Widget Universal Links From Lock Screen and Notification Center
我们有一个今日小部件可以深入 link 应用程序。当用户从主屏幕访问小部件时,深度 links 工作得很好。但是,当用户在设备锁定时访问小部件时,或者当用户从屏幕顶部向下滑动时,links 在 Safari 中打开。
我想知道是否还有其他人遇到过这个问题,如果遇到过,他们是如何解决的。
这是我们找到的解决方案 (Swift 4.1)。我们需要支持自定义 URL 方案来告诉 iOS 我们可以从今日小部件打开 links。这使用不同的 UIApplication 委托函数。除了实施 func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool
,我们还需要实施 func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
首先,在Info.plist
中,我们在CFBUndleURLTypes
下有我们支持的方案。
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>todayWidgetScheme</string>
</array>
</dict>
</array>
然后,同样在Info.plist
中,我们也列出了LSApplicationQueriesSchemes
下的方案。
<key>LSApplicationQueriesSchemes</key>
<array>
<string>todayWidgetScheme</string>
</array>
接下来,当从今天小部件打开 link 时,将 url 方案设置为 iOS 识别的 todayWidgetScheme。
func openAppFromTodayWidget() {
if let url = URL(string: "https://url.com") {
var components = URLComponents(url: url, resolvingAgainstBaseURL: true)
components?.scheme = "todayWidgetScheme"
if let todayWidgetUrl = components?.url {
extensionContext?.open(todayWidgetUrl)
}
}
}
最后,在AppDelegate.swift
中,当iOS要求应用处理通用link时,设置原来的url方案
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
if url.scheme == "todayWidgetScheme" {
var components = URLComponents(url: url, resolvingAgainstBaseURL: true)
components?.scheme = "https"
if let todayWidgetUrl = components?.url {
// do your thing
return true
}
}
return false
}
我们有一个今日小部件可以深入 link 应用程序。当用户从主屏幕访问小部件时,深度 links 工作得很好。但是,当用户在设备锁定时访问小部件时,或者当用户从屏幕顶部向下滑动时,links 在 Safari 中打开。
我想知道是否还有其他人遇到过这个问题,如果遇到过,他们是如何解决的。
这是我们找到的解决方案 (Swift 4.1)。我们需要支持自定义 URL 方案来告诉 iOS 我们可以从今日小部件打开 links。这使用不同的 UIApplication 委托函数。除了实施 func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool
,我们还需要实施 func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
首先,在Info.plist
中,我们在CFBUndleURLTypes
下有我们支持的方案。
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>todayWidgetScheme</string>
</array>
</dict>
</array>
然后,同样在Info.plist
中,我们也列出了LSApplicationQueriesSchemes
下的方案。
<key>LSApplicationQueriesSchemes</key>
<array>
<string>todayWidgetScheme</string>
</array>
接下来,当从今天小部件打开 link 时,将 url 方案设置为 iOS 识别的 todayWidgetScheme。
func openAppFromTodayWidget() {
if let url = URL(string: "https://url.com") {
var components = URLComponents(url: url, resolvingAgainstBaseURL: true)
components?.scheme = "todayWidgetScheme"
if let todayWidgetUrl = components?.url {
extensionContext?.open(todayWidgetUrl)
}
}
}
最后,在AppDelegate.swift
中,当iOS要求应用处理通用link时,设置原来的url方案
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
if url.scheme == "todayWidgetScheme" {
var components = URLComponents(url: url, resolvingAgainstBaseURL: true)
components?.scheme = "https"
if let todayWidgetUrl = components?.url {
// do your thing
return true
}
}
return false
}