23

iOS App Search Programming Guide的Universal Links部分,Apple 说:

如果您实例化 SFSafariViewController、WKWebView 或 UIWebView 对象来处理通用链接,iOS 会在 Safari 中打开您的网站,而不是打开您的应用程序。但是,如果用户从嵌入式 SFSafariViewController、WKWebView 或 UIWebView 对象中点击通用链接,iOS 会打开您的应用程序。

“处理通用链接”是什么意思?我不能用 , 或 来打开给定的SFSafariViewControllerURLWKWebViewUIWebView?它仅适用于 期间-[UIApplicationDelegate application:continueUserActivity:restorationHandler:],还是有超时?这是否意味着我们永远无法在SFSafariViewControllerWKWebView或中打开 URL UIWebView

4

2 回答 2

9

我不确定我是否完全理解你的问题。

只是为了涵盖基础知识,我将允许 Apple 解释什么是通用链接

通用链接允许用户在 WKWebView 和 UIWebView 视图和 Safari 页面中点击指向您网站的链接时打开您的应用程序,此外还有导致调用 openURL: 的链接,例如在邮件、消息和其他应用程序中出现的链接。

所以基本上,假设您正在使用 Twitter 客户端,并且通过时间线,您会遇到一条带有以下 YouTube 视频链接的推文:https ://youtu.be/ejQod8liXm0

如果您点击它,因为它是一个 HTTP URL,您会希望 Safari 会打开该链接。但是,我认为我们所有的 iOS 开发人员几乎都同意原生应用程序更好的事实,因此更好的用户体验将是官方 YouTube 应用程序打开视频,即使是从您的第三方客户端。

这是“通用链接”允许的;如果 YouTube 应用程序在 iOS 上将自己注册为负责处理https://www.youtube.com (*) 链接的应用程序,那么如果我们遵循 API 规则,iOS 生态系统中的每个人都会受益。如果您运行一个网站并且您希望您的任何内容在您的用户安装了它时触发您的官方 iOS 应用程序打开,或者提示用户是否愿意为更好的用户安装它,则会发生同样的事情经验(当然是为了帮助您的业务)。

因此,所有这些都结束了,让我们回到原文:

如果您实例化 SFSafariViewController、WKWebView 或 UIWebView 对象来处理通用链接,iOS 会在 Safari 中打开您的网站,而不是打开您的应用程序。但是,如果用户从嵌入式 SFSafariViewController、WKWebView 或 UIWebView 对象中点击通用链接,iOS 会打开您的应用程序。

这意味着,如果您的用户从您的应用程序中点击指向您的内容的通用链接(例如:http ://www.your-company.com/foo ),并且您不会在应用程序的代码中通过以下方式检测到这一点例如,一个正则表达式,而是实例化 a SFSafariViewControllerWKWebView或者UIWebView像打开它一样打开它,就像它是纽约时报或其他东西的常规链接一样,操作系统会理解,而不是在你的应用程序中打开它,你希望 Safari 来处理它你请记住:Universal Links 的全部目的是让用户通过本机应用程序而不是浏览器处理 URL 来获得更好的体验。

这就是第一句话所说的。至于第二个问题,它澄清了一个潜在的后续问题:如果用户从另一个不是我的应用程序的嵌入式浏览器点击指向我的内容的通用链接怎么办?然后,这句话说,操作系统将正常运行:它将打开您的应用程序,遵守通用链接规则。

TL;DR:您还需要在代码中检测应用程序中指向您的内容的通用链接,并处理它们。iOS 不会为您处理此问题。相反,如果您告诉操作系统从您的应用程序的嵌入式浏览器中打开指向您的应用程序内容的通用链接,它将完全按照指示执行。

编辑:如果您需要帮助决定是否要求SFSafariViewController-openURL:options:completitionHandler:API 打开 URL,此链接应该可以帮助您我的建议是先使用-openURL:options:completitionHandler:,如果不成功,再使用SFSafariViewController或类似的 .

希望这会有所帮助,并且我已经正确理解了您的问题。

干杯! 祝 iOS 11 编程愉快!:)

于 2017-07-31T12:00:41.987 回答
4

我用下面的 Swift 4 类解决了这个问题。如果可能,它还使用嵌入式 Safari 浏览器。您也可以在您的情况下采用类似的方法。

import UIKit
import SafariServices

class OpenLink {
    static func inAnyNativeWay(url: URL, dontPreferEmbeddedBrowser: Bool = false) { // OPEN AS UNIVERSAL LINK IF EXISTS else : EMBEDDED or EXTERNAL
        if #available(iOS 10.0, *) {
            // Try to open with owner universal link app
            UIApplication.shared.open(url, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly : true]) { (success) in
                if !success {
                    if dontPreferEmbeddedBrowser {
                        withRegularWay(url: url)
                    } else {
                        inAnyNativeBrowser(url: url)
                    }
                }
            }
        } else {
            if dontPreferEmbeddedBrowser {
                withRegularWay(url: url)
            } else {
                inAnyNativeBrowser(url: url)
            }
        }
    }
    private static func isItOkayToOpenUrlInSafariController(url: URL) -> Bool {
        return url.host != nil && (url.scheme == "http" || url.scheme == "https") //url.host!.contains("twitter.com") == false
    }
    static func inAnyNativeBrowser(url: URL) { // EMBEDDED or EXTERNAL BROWSER
        if isItOkayToOpenUrlInSafariController(url: url) {
            inEmbeddedSafariController(url: url)
        } else {
            withRegularWay(url: url)
        }
    }
    static func inEmbeddedSafariController(url: URL) { // EMBEDDED BROWSER ONLY
        let vc = SFSafariViewController(url: url, entersReaderIfAvailable: false)
        if #available(iOS 11.0, *) {
            vc.dismissButtonStyle = SFSafariViewController.DismissButtonStyle.close
        }
        mainViewControllerReference.present(vc, animated: true)
    }
    static func withRegularWay(url: URL) { // EXTERNAL BROWSER ONLY
        if #available(iOS 10.0, *) {
            UIApplication.shared.open(url, options: [UIApplication.OpenExternalURLOptionsKey(rawValue: "no"):"options"]) { (good) in
                if !good {
                    Logger.log(text: "There is no application on your device to open this link.")
                }
            }
        } else {
            UIApplication.shared.openURL(url)
        }
    }
}
于 2018-10-12T08:25:34.893 回答