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
}