【问题标题】:When can I use a SFSafariViewController, WKWebView, or UIWebView with universal links?我什么时候可以使用带有通用链接的 SFSafariViewController、WKWebView 或 UIWebView?
【发布时间】:2016-04-21 08:55:51
【问题描述】:

iOS App Search Programming GuideUniversal Links 部分,Apple 说:

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

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

【问题讨论】:

    标签: ios uiwebview wkwebview applinks sfsafariviewcontroller


    【解决方案1】:

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

    只是简单介绍一下,我让苹果解释一下what a Universal Link is

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

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

    如果您点击它,因为它是一个 HTTP URL,您会希望 Safari 会打开该链接。但是,我认为我们所有 iOS 开发者几乎都同意原生应用更好这一事实,因此官方 YouTube 应用打开视频会带来更好的用户体验 strong>,甚至来自您的第三方客户端。

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

    所以,说完这些,让我们回到原文:

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

    这意味着,如果您的用户在您的应用中点击指向您内容的通用链接(例如:http://www.your-company.com/foo),而您不会通过正则表达式在应用代码中检测到这一点,并且而是实例化 SFSafariViewControllerWKWebViewUIWebView 来打开它,就像它是指向 The New York Times 或其他东西的常规链接一样,操作系统会明白,不是在你的应用程序中打开它,你想要 Safari为您处理此问题记住:Universal Links 的全部目的是让用户通过本机应用而不是浏览器处理 URL 来获得更好的体验。

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

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

    编辑:如果您需要帮助决定是否要求 SFSafariViewController-openURL:options:completitionHandler: API 打开 URL,this link should help you我的建议是先使用-openURL:options:completitionHandler:,如果不成功,再使用SFSafariViewController 或类似的

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

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

    【讨论】:

    • > 如果你点击它,因为它是一个 HTTP URL,你会希望 Safari 打开链接如果 youtube 链接是普通的UITableViewCell,我将不得不“处理”youtube以某种方式链接,使用-[UIApplication openURL:options:completionHandler:]UIWebViewWKWebViewSFSafariViewController。我假设如果我用网络视图“处理”youtube 链接,系统将不会打开 youtube 应用程序,但 -openURL:options:completionHandler: 会。我怎么知道该做什么?
    • 以下链接提供了您正在寻找的答案,我认为:useyourloaf.com/blog/openurl-deprecated-in-ios10 这个想法是您可以先使用-openURL:options:completitionHandler:,如果不成功(成功@987654342 @ 是false),您可以使用SFSafariViewController 或类似名称。
    • 请更新您的答案以直接包含此内容,我会将您标记为正确。谢谢!
    • @HeathBorders 完成!
    【解决方案2】:

    我在下面的 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)
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-24
      • 2016-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      • 2010-12-28
      相关资源
      最近更新 更多